sun7i-kernel: update to latest gitrev + fix gcc6

This commit is contained in:
Juergen Buchmueller 2016-12-12 00:10:44 +01:00
parent 2c04e1dc49
commit 12746517d3
7 changed files with 554 additions and 4 deletions

View file

@ -0,0 +1,276 @@
From a66aaac889f09425ff0f3ddb27aca46ae02d6eea Mon Sep 17 00:00:00 2001
From: Joe Perches <joe@perches.com>
Date: Thu, 25 Jun 2015 15:01:02 -0700
Subject: [PATCH] compiler-gcc: integrate the various compiler-gcc[345].h files
As gcc major version numbers are going to advance rather rapidly in the
future, there's no real value in separate files for each compiler
version.
Deduplicate some of the macros #defined in each file too.
Neaten comments using normal kernel commenting style.
Upstream-Status: Backport
Signed-off-by: Joe Perches <joe@perches.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Segher Boessenkool <segher@kernel.crashing.org>
Cc: Sasha Levin <levinsasha928@gmail.com>
Cc: Anton Blanchard <anton@samba.org>
Cc: Alan Modra <amodra@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jonathan Liu <net147@gmail.com>
---
include/linux/compiler-gcc.h | 120 ++++++++++++++++++++++++++++++++++++++++--
include/linux/compiler-gcc3.h | 23 --------
include/linux/compiler-gcc4.h | 74 --------------------------
3 files changed, 116 insertions(+), 101 deletions(-)
delete mode 100644 include/linux/compiler-gcc3.h
delete mode 100644 include/linux/compiler-gcc4.h
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 7970e31..727add9 100644
--- include/linux/compiler-gcc.h
+++ include/linux/compiler-gcc.h
@@ -97,10 +97,122 @@
#define __maybe_unused __attribute__((unused))
#define __always_unused __attribute__((unused))
-#define __gcc_header(x) #x
-#define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h)
-#define gcc_header(x) _gcc_header(x)
-#include gcc_header(__GNUC__)
+/* gcc version specific checks */
+
+#if GCC_VERSION < 30200
+# error Sorry, your compiler is too old - please upgrade it.
+#endif
+
+#if GCC_VERSION < 30300
+# define __used __attribute__((__unused__))
+#else
+# define __used __attribute__((__used__))
+#endif
+
+#ifdef CONFIG_GCOV_KERNEL
+# if GCC_VERSION < 30400
+# error "GCOV profiling support for gcc versions below 3.4 not included"
+# endif /* __GNUC_MINOR__ */
+#endif /* CONFIG_GCOV_KERNEL */
+
+#if GCC_VERSION >= 30400
+#define __must_check __attribute__((warn_unused_result))
+#endif
+
+#if GCC_VERSION >= 40000
+
+/* GCC 4.1.[01] miscompiles __weak */
+#ifdef __KERNEL__
+# if GCC_VERSION >= 40100 && GCC_VERSION <= 40101
+# error Your version of gcc miscompiles the __weak directive
+# endif
+#endif
+
+#define __used __attribute__((__used__))
+#define __compiler_offsetof(a, b) \
+ __builtin_offsetof(a, b)
+
+#if GCC_VERSION >= 40100 && GCC_VERSION < 40600
+# define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
+#endif
+
+#if GCC_VERSION >= 40300
+/* Mark functions as cold. gcc will assume any path leading to a call
+ * to them will be unlikely. This means a lot of manual unlikely()s
+ * are unnecessary now for any paths leading to the usual suspects
+ * like BUG(), printk(), panic() etc. [but let's keep them for now for
+ * older compilers]
+ *
+ * Early snapshots of gcc 4.3 don't support this and we can't detect this
+ * in the preprocessor, but we can live with this because they're unreleased.
+ * Maketime probing would be overkill here.
+ *
+ * gcc also has a __attribute__((__hot__)) to move hot functions into
+ * a special section, but I don't see any sense in this right now in
+ * the kernel context
+ */
+#define __cold __attribute__((__cold__))
+
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
+
+#ifndef __CHECKER__
+# define __compiletime_warning(message) __attribute__((warning(message)))
+# define __compiletime_error(message) __attribute__((error(message)))
+#endif /* __CHECKER__ */
+#endif /* GCC_VERSION >= 40300 */
+
+#if GCC_VERSION >= 40500
+/*
+ * Mark a position in code as unreachable. This can be used to
+ * suppress control flow warnings after asm blocks that transfer
+ * control elsewhere.
+ *
+ * Early snapshots of gcc 4.5 don't support this and we can't detect
+ * this in the preprocessor, but we can live with this because they're
+ * unreleased. Really, we need to have autoconf for the kernel.
+ */
+#define unreachable() __builtin_unreachable()
+
+/* Mark a function definition as prohibited from being cloned. */
+#define __noclone __attribute__((__noclone__))
+
+#endif /* GCC_VERSION >= 40500 */
+
+#if GCC_VERSION >= 40600
+/*
+ * Tell the optimizer that something else uses this function or variable.
+ */
+#define __visible __attribute__((externally_visible))
+#endif
+
+/*
+ * GCC 'asm goto' miscompiles certain code sequences:
+ *
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
+ *
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
+ *
+ * (asm goto is automatically volatile - the naming reflects this.)
+ */
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
+
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
+#if GCC_VERSION >= 40400
+#define __HAVE_BUILTIN_BSWAP32__
+#define __HAVE_BUILTIN_BSWAP64__
+#endif
+#if GCC_VERSION >= 40800 || (defined(__powerpc__) && GCC_VERSION >= 40600)
+#define __HAVE_BUILTIN_BSWAP16__
+#endif
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
+
+#if GCC_VERSION >= 50000
+#define KASAN_ABI_VERSION 4
+#elif GCC_VERSION >= 40902
+#define KASAN_ABI_VERSION 3
+#endif
+
+#endif /* gcc version >= 40000 specific checks */
#if !defined(__noclone)
#define __noclone /* not needed */
diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h
deleted file mode 100644
index 37d4124..0000000
--- include/linux/compiler-gcc3.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __LINUX_COMPILER_H
-#error "Please don't include <linux/compiler-gcc3.h> directly, include <linux/compiler.h> instead."
-#endif
-
-#if __GNUC_MINOR__ < 2
-# error Sorry, your compiler is too old - please upgrade it.
-#endif
-
-#if __GNUC_MINOR__ >= 3
-# define __used __attribute__((__used__))
-#else
-# define __used __attribute__((__unused__))
-#endif
-
-#if __GNUC_MINOR__ >= 4
-#define __must_check __attribute__((warn_unused_result))
-#endif
-
-#ifdef CONFIG_GCOV_KERNEL
-# if __GNUC_MINOR__ < 4
-# error "GCOV profiling support for gcc versions below 3.4 not included"
-# endif /* __GNUC_MINOR__ */
-#endif /* CONFIG_GCOV_KERNEL */
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
deleted file mode 100644
index 91b1aa8..0000000
--- include/linux/compiler-gcc4.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef __LINUX_COMPILER_H
-#error "Please don't include <linux/compiler-gcc4.h> directly, include <linux/compiler.h> instead."
-#endif
-
-/* GCC 4.1.[01] miscompiles __weak */
-#ifdef __KERNEL__
-# if __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ <= 1
-# error Your version of gcc miscompiles the __weak directive
-# endif
-#endif
-
-#define __used __attribute__((__used__))
-#define __must_check __attribute__((warn_unused_result))
-#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
-
-#if __GNUC_MINOR__ >= 3
-/* Mark functions as cold. gcc will assume any path leading to a call
- to them will be unlikely. This means a lot of manual unlikely()s
- are unnecessary now for any paths leading to the usual suspects
- like BUG(), printk(), panic() etc. [but let's keep them for now for
- older compilers]
-
- Early snapshots of gcc 4.3 don't support this and we can't detect this
- in the preprocessor, but we can live with this because they're unreleased.
- Maketime probing would be overkill here.
-
- gcc also has a __attribute__((__hot__)) to move hot functions into
- a special section, but I don't see any sense in this right now in
- the kernel context */
-#define __cold __attribute__((__cold__))
-
-#define __linktime_error(message) __attribute__((__error__(message)))
-
-/*
- * GCC 'asm goto' miscompiles certain code sequences:
- *
- * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
- *
- * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
- * Fixed in GCC 4.8.2 and later versions.
- *
- * (asm goto is automatically volatile - the naming reflects this.)
- */
-#if GCC_VERSION <= 40801
-# define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
-#else
-# define asm_volatile_goto(x...) do { asm goto(x); } while (0)
-#endif
-
-#if __GNUC_MINOR__ >= 5
-/*
- * Mark a position in code as unreachable. This can be used to
- * suppress control flow warnings after asm blocks that transfer
- * control elsewhere.
- *
- * Early snapshots of gcc 4.5 don't support this and we can't detect
- * this in the preprocessor, but we can live with this because they're
- * unreleased. Really, we need to have autoconf for the kernel.
- */
-#define unreachable() __builtin_unreachable()
-
-/* Mark a function definition as prohibited from being cloned. */
-#define __noclone __attribute__((__noclone__))
-
-#endif
-#endif
-
-#if __GNUC_MINOR__ > 0
-#define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
-#endif
-#if __GNUC_MINOR__ >= 4 && !defined(__CHECKER__)
-#define __compiletime_warning(message) __attribute__((warning(message)))
-#define __compiletime_error(message) __attribute__((error(message)))
-#endif
--
2.10.0

View file

@ -0,0 +1,16 @@
The function is defined in the source, so don't inline it in the header.
--- arch/arm/include/asm/ftrace.h 2014-10-22 23:53:32.000000000 +0200
+++ arch/arm/include/asm/ftrace.h 2016-12-11 22:57:55.065090536 +0100
@@ -45,10 +45,7 @@
#else
-extern inline void *return_address(unsigned int level)
-{
- return NULL;
-}
+extern void *return_address(unsigned int level);
#endif

View file

@ -0,0 +1,198 @@
Defining a function "extern inline" or "extern __inline" makes it appear in the
object files of source files including the header multiple times. This leads to
multiply defined symbols when linking. Remove then "extern" where appropriate.
--- drivers/net/wireless/rtl8188eu/include/ieee80211.h 2015-03-15 20:30:43.000000000 +0100
+++ drivers/net/wireless/rtl8188eu/include/ieee80211.h 2016-12-11 23:48:07.113462416 +0100
@@ -1188,12 +1188,12 @@
(((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \
(((Addr[5]) & 0xff) == 0xff))
#else
-extern __inline int is_multicast_mac_addr(const u8 *addr)
+inline int is_multicast_mac_addr(const u8 *addr)
{
return ((addr[0] != 0xff) && (0x01 & addr[0]));
}
-extern __inline int is_broadcast_mac_addr(const u8 *addr)
+inline int is_broadcast_mac_addr(const u8 *addr)
{
return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
--- drivers/net/wireless/rtl8189es/include/ieee80211.h 2015-03-15 20:30:43.000000000 +0100
+++ drivers/net/wireless/rtl8189es/include/ieee80211.h 2016-12-11 23:46:24.353521931 +0100
@@ -1188,12 +1188,12 @@
(((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \
(((Addr[5]) & 0xff) == 0xff))
#else
-extern __inline int is_multicast_mac_addr(const u8 *addr)
+inline int is_multicast_mac_addr(const u8 *addr)
{
return ((addr[0] != 0xff) && (0x01 & addr[0]));
}
-extern __inline int is_broadcast_mac_addr(const u8 *addr)
+inline int is_broadcast_mac_addr(const u8 *addr)
{
return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
--- drivers/net/wireless/rtl8192cu/include/ieee80211.h 2015-03-15 20:30:43.000000000 +0100
+++ drivers/net/wireless/rtl8192cu/include/ieee80211.h 2016-12-11 23:47:59.585466757 +0100
@@ -1149,12 +1149,12 @@
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
-extern __inline int is_multicast_mac_addr(const u8 *addr)
+inline int is_multicast_mac_addr(const u8 *addr)
{
return ((addr[0] != 0xff) && (0x01 & addr[0]));
}
-extern __inline int is_broadcast_mac_addr(const u8 *addr)
+inline int is_broadcast_mac_addr(const u8 *addr)
{
return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
@@ -1177,7 +1177,7 @@
#define IEEE_G (1<<2)
#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
-extern __inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
{
/* Single white space is for Linksys APs */
if (essid_len == 1 && essid[0] == ' ')
@@ -1193,7 +1193,7 @@
return 1;
}
-extern __inline int ieee80211_get_hdrlen(u16 fc)
+inline int ieee80211_get_hdrlen(u16 fc)
{
int hdrlen = 24;
--- drivers/net/wireless/rtl8723as/include/ieee80211.h 2015-03-15 20:30:43.000000000 +0100
+++ drivers/net/wireless/rtl8723as/include/ieee80211.h 2016-12-11 23:46:57.248502814 +0100
@@ -1176,12 +1176,12 @@
(((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \
(((Addr[5]) & 0xff) == 0xff))
#else
-extern __inline int is_multicast_mac_addr(const u8 *addr)
+inline int is_multicast_mac_addr(const u8 *addr)
{
return ((addr[0] != 0xff) && (0x01 & addr[0]));
}
-extern __inline int is_broadcast_mac_addr(const u8 *addr)
+inline int is_broadcast_mac_addr(const u8 *addr)
{
return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
--- drivers/staging/rtl8187se/ieee80211/ieee80211.h 2015-03-15 20:30:43.000000000 +0100
+++ drivers/staging/rtl8187se/ieee80211/ieee80211.h 2016-12-11 23:45:36.905549616 +0100
@@ -1221,7 +1221,7 @@
return ((struct ieee80211_device *)netdev_priv(dev))->priv;
}
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
{
/* Single white space is for Linksys APs */
if (essid_len == 1 && essid[0] == ' ')
@@ -1237,7 +1237,7 @@
return 1;
}
-extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
+inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
{
/*
* It is possible for both access points and our device to support
@@ -1263,7 +1263,7 @@
return 0;
}
-extern inline int ieee80211_get_hdrlen(u16 fc)
+inline int ieee80211_get_hdrlen(u16 fc)
{
int hdrlen = 24;
@@ -1447,12 +1447,12 @@
extern const long ieee80211_wlan_frequencies[];
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
{
ieee->scans++;
}
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+inline int ieee80211_get_scans(struct ieee80211_device *ieee)
{
return ieee->scans;
}
--- drivers/staging/rtl8192u/ieee80211/ieee80211.h 2015-03-15 20:30:43.000000000 +0100
+++ drivers/staging/rtl8192u/ieee80211/ieee80211.h 2016-12-11 23:46:10.214530167 +0100
@@ -2251,7 +2251,7 @@
return ((struct ieee80211_device *)netdev_priv(dev))->priv;
}
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
{
/* Single white space is for Linksys APs */
if (essid_len == 1 && essid[0] == ' ')
@@ -2267,7 +2267,7 @@
return 1;
}
-extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
+inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
{
/*
* It is possible for both access points and our device to support
@@ -2293,7 +2293,7 @@
return 0;
}
-extern inline int ieee80211_get_hdrlen(u16 fc)
+inline int ieee80211_get_hdrlen(u16 fc)
{
int hdrlen = IEEE80211_3ADDR_LEN;
@@ -2579,12 +2579,12 @@
extern const long ieee80211_wlan_frequencies[];
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
{
ieee->scans++;
}
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+inline int ieee80211_get_scans(struct ieee80211_device *ieee)
{
return ieee->scans;
}
--- drivers/staging/rtl8712/ieee80211.h 2015-03-15 20:30:43.000000000 +0100
+++ drivers/staging/rtl8712/ieee80211.h 2016-12-11 23:45:54.550539305 +0100
@@ -734,7 +734,7 @@
#define IEEE_G (1<<2)
#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
{
/* Single white space is for Linksys APs */
if (essid_len == 1 && essid[0] == ' ')
@@ -748,7 +748,7 @@
return 1;
}
-extern inline int ieee80211_get_hdrlen(u16 fc)
+inline int ieee80211_get_hdrlen(u16 fc)
{
int hdrlen = 24;

View file

@ -0,0 +1,18 @@
The order of variable definitions and code can't be mixed with ISOC90
--- drivers/net/wireless/rtxx7x/os/linux/usb_main_dev.c 2015-03-15 20:30:43.000000000 +0100
+++ drivers/net/wireless/rtxx7x/os/linux/usb_main_dev.c 2016-12-11 23:17:00.710634654 +0100
@@ -444,11 +444,11 @@
struct net_device *net_dev;
VOID *pAd = usb_get_intfdata(intf);
- late_resume_flag = TRUE;
-
#ifdef USB_SUPPORT_SELECTIVE_SUSPEND
UCHAR Flag;
#endif
+
+ late_resume_flag = TRUE;
#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER)
if ((RT_IS_EARLYSUSPEND_REGISTERED((PRTMP_ADAPTER)pAd)) && (late_resume_flag == TRUE)){
VIRTUAL_IF_DOWN((VOID *)pAd);

View file

@ -0,0 +1,23 @@
Make these inline definitions "extern inline" to keep a copy of
the code in the object files.
--- drivers/input/mouse/lifebook.h 2015-03-15 20:30:43.000000000 +0100
+++ drivers/input/mouse/lifebook.h 2016-12-11 23:57:26.116108248 +0100
@@ -16,14 +16,14 @@
int lifebook_detect(struct psmouse *psmouse, bool set_properties);
int lifebook_init(struct psmouse *psmouse);
#else
-inline void lifebook_module_init(void)
+extern inline void lifebook_module_init(void)
{
}
-inline int lifebook_detect(struct psmouse *psmouse, bool set_properties)
+extern inline int lifebook_detect(struct psmouse *psmouse, bool set_properties)
{
return -ENOSYS;
}
-inline int lifebook_init(struct psmouse *psmouse)
+extern inline int lifebook_init(struct psmouse *psmouse)
{
return -ENOSYS;
}

View file

@ -0,0 +1,19 @@
Make these inline definitions "extern inline" to keep a copy of
the code in the object files.
--- drivers/input/mouse/sentelic.h 2015-03-15 20:30:43.000000000 +0100
+++ drivers/input/mouse/sentelic.h 2016-12-11 23:59:42.772013703 +0100
@@ -115,11 +115,11 @@
extern int fsp_detect(struct psmouse *psmouse, bool set_properties);
extern int fsp_init(struct psmouse *psmouse);
#else
-inline int fsp_detect(struct psmouse *psmouse, bool set_properties)
+extern inline int fsp_detect(struct psmouse *psmouse, bool set_properties)
{
return -ENOSYS;
}
-inline int fsp_init(struct psmouse *psmouse)
+extern inline int fsp_init(struct psmouse *psmouse)
{
return -ENOSYS;
}

View file

@ -1,12 +1,12 @@
# Template file for 'sun7i-kernel'
#
# Latest commit as of 20151114
_githash="a8f8ba9ba383c2358d67b4dcaa5ce5cd4f0dd587"
# Latest commit as of 20150315
_githash="d47d367036be38c5180632ec8a3ad169a4593a88"
_gitshort="${_githash:0:7}"
pkgname=sun7i-kernel
version=3.4.104
revision=1
revision=2
maintainer="Juan RP <xtraeme@voidlinux.eu>"
homepage="http://www.kernel.org"
license="GPL-2"
@ -16,7 +16,7 @@ _patchurl="https://raw.githubusercontent.com/archlinuxarm/PKGBUILDs/5c82068/core
distfiles="https://github.com/linux-sunxi/linux-sunxi/archive/${_githash}.tar.gz
${_patchurl}/0001-Backport-firmware-loader.patch
${_patchurl}/0001-Backport-msdos-partition-UUIDs.patch"
checksum="c7f5881b6338a94deb78fdb02dee57f7db20170fd80ddbe8663e8d0791db1ebe
checksum="614a6fc47beb64a3b9b55a772a4cea0192bb358254e0b717de1ea031d2d6864f
eeceb6459f2f40c91a6a5be8d8c60e68dec2631ec84d6165721edacb059507c4
f0bba58788f090dd213df0bde1ea0ce38999a8d28bebe443c899cb9cbc2b5eed"