From 1010fc775a79a6a1f9b6b6ca1c14886b31974fce Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 28 Jul 2020 09:54:59 -0400 Subject: [PATCH] import ledmon-0.94-1.el8 --- .gitignore | 2 +- .ledmon.metadata | 2 +- ...n_systemd_service_file_are_generated.patch | 54 --- ...mp_fix_the_activity_indicator_states.patch | 26 -- ..._sgpio_correct_use_of_packed_structs.patch | 320 ------------------ SOURCES/0004-dont_build_with_werror.patch | 29 -- SPECS/ledmon.spec | 14 +- 7 files changed, 7 insertions(+), 440 deletions(-) delete mode 100644 SOURCES/0001-ledmon_paths_in_systemd_service_file_are_generated.patch delete mode 100644 SOURCES/0002-smp_fix_the_activity_indicator_states.patch delete mode 100644 SOURCES/0003-amd_sgpio_correct_use_of_packed_structs.patch delete mode 100644 SOURCES/0004-dont_build_with_werror.patch diff --git a/.gitignore b/.gitignore index 4fcffee..5150a85 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/ledmon-0.93.tar.gz +SOURCES/ledmon-0.94.tar.gz diff --git a/.ledmon.metadata b/.ledmon.metadata index 564d694..a992e98 100644 --- a/.ledmon.metadata +++ b/.ledmon.metadata @@ -1 +1 @@ -c5a3c52b1dee64972ea5fba8cc3f92689360d6c9 SOURCES/ledmon-0.93.tar.gz +5f4bdf071ced03627705fdeb8659bd2ea2770e9d SOURCES/ledmon-0.94.tar.gz diff --git a/SOURCES/0001-ledmon_paths_in_systemd_service_file_are_generated.patch b/SOURCES/0001-ledmon_paths_in_systemd_service_file_are_generated.patch deleted file mode 100644 index aa681df..0000000 --- a/SOURCES/0001-ledmon_paths_in_systemd_service_file_are_generated.patch +++ /dev/null @@ -1,54 +0,0 @@ -commit 13040e80dec77d7c9e9e3636f2068fce9e056dc2 -Author: Krzysztof Smolinski -Date: Sun Nov 10 18:58:01 2019 +0100 - - ledmon: paths in systemd service file are generated - - Ledmon service file contained hardcoded path to ledmon executable. - This patch places correct installation path of ledmon in systemd - service file. - - Signed-off-by: Krzysztof Smolinski - -diff --git a/Makefile.am b/Makefile.am -index 0bfc188..63bf8a3 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -21,5 +21,5 @@ if SYSTEMD_CONDITION - endif - - SUBDIRS = doc src $(OPTIONAL_SUBDIR) --EXTRA_DIST = config/config.h systemd/ledmon.service -+EXTRA_DIST = config/config.h systemd/ledmon.service.in - dist_doc_DATA = README -diff --git a/systemd/Makefile.am b/systemd/Makefile.am -index 4303628..962b122 100644 ---- a/systemd/Makefile.am -+++ b/systemd/Makefile.am -@@ -18,6 +18,12 @@ - - # Installation directory of ledmon systemd service unit. - systemddir = @SYSTEMD_PATH@ -+SED = sed -+ -+CLEANFILES = ledmon.service ledmon.service.tmp - - systemd_DATA = ledmon.service - -+ledmon.service : ledmon.service.in -+ $(SED) -e 's|@sbindir[@]|$(sbindir)|g' < $< > $@.tmp -+ mv $@.tmp $@ -diff --git a/systemd/ledmon.service b/systemd/ledmon.service.in -similarity index 76% -rename from systemd/ledmon.service -rename to systemd/ledmon.service.in -index d2fa08c..059fd95 100644 ---- a/systemd/ledmon.service -+++ b/systemd/ledmon.service.in -@@ -7,5 +7,5 @@ WantedBy=multi-user.target - [Service] - Type=simple - User=root --ExecStart=/usr/sbin/ledmon --foreground -+ExecStart=@sbindir@/ledmon --foreground - Restart=on-failure diff --git a/SOURCES/0002-smp_fix_the_activity_indicator_states.patch b/SOURCES/0002-smp_fix_the_activity_indicator_states.patch deleted file mode 100644 index 5ca2a66..0000000 --- a/SOURCES/0002-smp_fix_the_activity_indicator_states.patch +++ /dev/null @@ -1,26 +0,0 @@ -commit dc6d2c546b938b106f4f8ba708989193d9a6c90d -Author: Artur Paszkiewicz -Date: Fri Nov 29 11:56:41 2019 +0100 - - smp: fix the activity indicator states - - The values for SOF and EOF were interchanged, which caused an incorrect - default value to be used (100b instead of 101b). - - Signed-off-by: Artur Paszkiewicz - -diff --git a/src/smp.c b/src/smp.c -index b893d76..2c089f8 100644 ---- a/src/smp.c -+++ b/src/smp.c -@@ -61,8 +61,8 @@ - #define LED_ON 1 - #define LED_4HZ 2 - #define LED_I4HZ 3 --#define LED_SOF 4 --#define LED_EOF 5 -+#define LED_EOF 4 -+#define LED_SOF 5 - #define LED_2HZ 6 - #define LED_I2HZ 7 - diff --git a/SOURCES/0003-amd_sgpio_correct_use_of_packed_structs.patch b/SOURCES/0003-amd_sgpio_correct_use_of_packed_structs.patch deleted file mode 100644 index ad7be1a..0000000 --- a/SOURCES/0003-amd_sgpio_correct_use_of_packed_structs.patch +++ /dev/null @@ -1,320 +0,0 @@ -commit d4687596f64190afd772bfd5404e56b411424eab -Author: Nathan Fontenot -Date: Mon Dec 2 10:59:04 2019 -0600 - - amd_sgpio: Correct use of packed structs - - With gcc-9 the -Waddress-of-packed-member flag is enabled by default to - prevent access to unaligned members of a struct on systems that do not - support unaligned accesses. - - To correct this the amd_sgpio code is updated to no longer use pointers - to packed structures. - - Signed-off-by: Nathan Fontenot - -diff --git a/src/amd_sgpio.c b/src/amd_sgpio.c -index 8150e4c..efe1c26 100644 ---- a/src/amd_sgpio.c -+++ b/src/amd_sgpio.c -@@ -330,112 +330,114 @@ static int _send_sgpio_register(const char *em_buffer_path, void *reg, - return 0; - } - --static void _init_sgpio_hdr(sgpio_hdr_t *hdr, int data_size, int msg_size) -+static sgpio_hdr_t _init_sgpio_hdr(int data_size, int msg_size) - { -- memset(hdr, 0, sizeof(*hdr)); -+ sgpio_hdr_t hdr = 0; - -- set_sgpio_hdr_msg_type(hdr, SGPIO_HDR_MSG_TYPE_SGPIO); -- set_sgpio_hdr_data_size(hdr, data_size); -- set_sgpio_hdr_msg_size(hdr, msg_size); -+ set_sgpio_hdr_msg_type(&hdr, SGPIO_HDR_MSG_TYPE_SGPIO); -+ set_sgpio_hdr_data_size(&hdr, data_size); -+ set_sgpio_hdr_msg_size(&hdr, msg_size); -+ -+ return hdr; - } - --static void _dump_sgpio_hdr(sgpio_hdr_t *hdr) -+static void _dump_sgpio_hdr(const char *type, sgpio_hdr_t hdr) - { -- log_debug("SGPIO Header\n"); -- log_debug(REG_FMT_2, "message type", get_sgpio_hdr_msg_type(hdr), -- "data size", get_sgpio_hdr_data_size(hdr)); -- log_debug(REG_FMT_1, "message size", get_sgpio_hdr_msg_size(hdr)); -+ log_debug("%s SGPIO Header: %08x\n", type, hdr); -+ log_debug(REG_FMT_2, "message type", get_sgpio_hdr_msg_type(&hdr), -+ "data size", get_sgpio_hdr_data_size(&hdr)); -+ log_debug(REG_FMT_1, "message size", get_sgpio_hdr_msg_size(&hdr)); - } - --static void _init_sgpio_req(sgpio_req_t *req, int frame_type, int function, -- int reg_type, int reg_index, int reg_count) -+static sgpio_req_t _init_sgpio_req(int frame_type, int function, -+ int reg_type, int reg_index, -+ int reg_count) - { -- memset(req, 0, sizeof(*req)); -+ sgpio_req_t req = 0; -+ -+ set_sgpio_req_frame_type(&req, frame_type); -+ set_sgpio_req_function(&req, function); -+ set_sgpio_req_reg_type(&req, reg_type); -+ set_sgpio_req_reg_index(&req, reg_index); -+ set_sgpio_req_reg_count(&req, reg_count); - -- set_sgpio_req_frame_type(req, frame_type); -- set_sgpio_req_function(req, function); -- set_sgpio_req_reg_type(req, reg_type); -- set_sgpio_req_reg_index(req, reg_index); -- set_sgpio_req_reg_count(req, reg_count); -+ return req; - } - --static void _dump_sgpio_req(sgpio_req_t *req) -+static void _dump_sgpio_req(const char *type, sgpio_req_t req) - { -- log_debug("SGPIO Request Register:\n"); -- log_debug(REG_FMT_2, "frame type", get_sgpio_req_frame_type(req), -- "function", get_sgpio_req_function(req)); -- log_debug(REG_FMT_2, "register type", get_sgpio_req_reg_type(req), -- "register index", get_sgpio_req_reg_index(req)); -- log_debug(REG_FMT_1, "register count", get_sgpio_req_reg_count(req)); -+ uint32_t *r = (uint32_t *)&req; -+ -+ log_debug("%s SGPIO Request Register: %08x %08x\n", type, r[0], r[1]); -+ log_debug(REG_FMT_2, "frame type", get_sgpio_req_frame_type(&req), -+ "function", get_sgpio_req_function(&req)); -+ log_debug(REG_FMT_2, "register type", get_sgpio_req_reg_type(&req), -+ "register index", get_sgpio_req_reg_index(&req)); -+ log_debug(REG_FMT_1, "register count", get_sgpio_req_reg_count(&req)); - } - --static void _init_sgpio_cfg(sgpio_cfg_t *cfg, int gpio_enable, int blink_a, -- int blink_b, int force_off, int max_on, -- int stretch_off, int stretch_on) -+static sgpio_cfg_t _init_sgpio_cfg(int gpio_enable, int blink_a, -+ int blink_b, int force_off, int max_on, -+ int stretch_off, int stretch_on) - { -- memset(cfg, 0, sizeof(*cfg)); -+ sgpio_cfg_t cfg = 0; - - if (gpio_enable) -- set_sgpio_cfg_gpio_enable(cfg, 1); -- -- set_sgpio_cfg_blink_gen_a(cfg, blink_a); -- set_sgpio_cfg_blink_gen_b(cfg, blink_b); -- set_sgpio_cfg_max_on(cfg, max_on); -- set_sgpio_cfg_force_off(cfg, force_off); -- set_sgpio_cfg_stretch_on(cfg, stretch_on); -- set_sgpio_cfg_stretch_off(cfg, stretch_off); -+ set_sgpio_cfg_gpio_enable(&cfg, 1); -+ -+ set_sgpio_cfg_blink_gen_a(&cfg, blink_a); -+ set_sgpio_cfg_blink_gen_b(&cfg, blink_b); -+ set_sgpio_cfg_max_on(&cfg, max_on); -+ set_sgpio_cfg_force_off(&cfg, force_off); -+ set_sgpio_cfg_stretch_on(&cfg, stretch_on); -+ set_sgpio_cfg_stretch_off(&cfg, stretch_off); -+ -+ return cfg; - } - --static void _dump_sgpio_cfg(sgpio_cfg_t *cfg) -+static void _dump_sgpio_cfg(const char *type, sgpio_cfg_t cfg) - { -- log_debug("SGPIO Configuration Register:\n"); -- log_debug(REG_FMT_2, "version", get_sgpio_cfg_version(cfg), -- "gp register count", get_sgpio_cfg_gp_reg_count(cfg)); -+ uint32_t *r = (uint32_t *)&cfg; -+ -+ log_debug("%s SGPIO Configuration Register: %08x %08x\n", type, -+ r[0], r[1]); -+ log_debug(REG_FMT_2, "version", get_sgpio_cfg_version(&cfg), -+ "gp register count", get_sgpio_cfg_gp_reg_count(&cfg)); - log_debug(REG_FMT_2, "cfg register count", -- get_sgpio_cfg_cfg_reg_count(cfg), "gpio enabled", -- get_sgpio_cfg_gpio_enable(cfg)); -- log_debug(REG_FMT_2, "drive count", get_sgpio_cfg_drive_count(cfg), -- "blink gen rate A", get_sgpio_cfg_blink_gen_a(cfg)); -+ get_sgpio_cfg_cfg_reg_count(&cfg), "gpio enabled", -+ get_sgpio_cfg_gpio_enable(&cfg)); -+ log_debug(REG_FMT_2, "drive count", get_sgpio_cfg_drive_count(&cfg), -+ "blink gen rate A", get_sgpio_cfg_blink_gen_a(&cfg)); - - log_debug(REG_FMT_2, "blink gen rate B", -- get_sgpio_cfg_blink_gen_b(cfg), "force activity off", -- get_sgpio_cfg_force_off(cfg)); -- log_debug(REG_FMT_2, "max activity on", get_sgpio_cfg_max_on(cfg), -- "stretch activity off", get_sgpio_cfg_stretch_off(cfg)); -+ get_sgpio_cfg_blink_gen_b(&cfg), "force activity off", -+ get_sgpio_cfg_force_off(&cfg)); -+ log_debug(REG_FMT_2, "max activity on", get_sgpio_cfg_max_on(&cfg), -+ "stretch activity off", get_sgpio_cfg_stretch_off(&cfg)); - log_debug(REG_FMT_1, "stretch activity on", -- get_sgpio_cfg_stretch_on(cfg)); -+ get_sgpio_cfg_stretch_on(&cfg)); - } - --static void _init_sgpio_amd(sgpio_amd_t *amd, int initiator, int polarity, -- int bypass, int normal) -+static sgpio_amd_t _init_sgpio_amd(int initiator, int polarity, -+ int bypass, int normal) - { -- memset(amd, 0, sizeof(*amd)); -+ sgpio_amd_t amd = 0; - -- set_sgpio_amd_initiator(amd, initiator); -- set_sgpio_amd_polarity_flip(amd, polarity); -- set_sgpio_amd_bypass_enable(amd, bypass); -- set_sgpio_amd_return_to_normal(amd, normal); --} -+ set_sgpio_amd_initiator(&amd, initiator); -+ set_sgpio_amd_polarity_flip(&amd, polarity); -+ set_sgpio_amd_bypass_enable(&amd, bypass); -+ set_sgpio_amd_return_to_normal(&amd, normal); - --static void _dump_sgpio_amd(sgpio_amd_t *amd) --{ -- log_debug("SGPIO AMD Register\n"); -- log_debug(REG_FMT_2, "initiator", get_sgpio_amd_initiator(amd), -- "polarity", get_sgpio_amd_polarity_flip(amd)); -- log_debug(REG_FMT_2, "bypass enable", get_sgpio_amd_bypass_enable(amd), -- "return to normal", get_sgpio_amd_return_to_normal(amd)); -+ return amd; - } - --static void _dump_cfg_register(struct config_register *cfg_reg) -+static void _dump_sgpio_amd(const char *type, sgpio_amd_t amd) - { -- uint32_t *reg = (uint32_t *)cfg_reg; -- -- log_info("CFG Register: %08x %08x %08x %08x %08x", -- reg[0], reg[1], reg[2], reg[3], reg[4]); -- -- _dump_sgpio_hdr(&cfg_reg->hdr); -- _dump_sgpio_req(&cfg_reg->req); -- _dump_sgpio_cfg(&cfg_reg->cfg); -+ log_debug("%s SGPIO AMD Register: %08x\n", type, amd); -+ log_debug(REG_FMT_2, "initiator", get_sgpio_amd_initiator(&amd), -+ "polarity", get_sgpio_amd_polarity_flip(&amd)); -+ log_debug(REG_FMT_2, "bypass enable", get_sgpio_amd_bypass_enable(&amd), -+ "return to normal", get_sgpio_amd_return_to_normal(&amd)); - } - - static int _write_cfg_register(const char *em_buffer_path, -@@ -443,53 +445,49 @@ static int _write_cfg_register(const char *em_buffer_path, - { - struct config_register cfg_reg; - -- _init_sgpio_hdr(&cfg_reg.hdr, 0, sizeof(cfg_reg)); -- _init_sgpio_req(&cfg_reg.req, 0x40, 0x82, SGPIO_REQ_REG_TYPE_CFG, 0, 2); -+ cfg_reg.hdr = _init_sgpio_hdr(0, sizeof(cfg_reg)); -+ cfg_reg.req = _init_sgpio_req(0x40, 0x82, SGPIO_REQ_REG_TYPE_CFG, -+ 0, 2); - - if (cache->blink_gen_a) - cache->blink_gen_b = ibpi_pattern[ibpi]; - else - cache->blink_gen_a = ibpi_pattern[ibpi]; - -- _init_sgpio_cfg(&cfg_reg.cfg, 1, cache->blink_gen_a, cache->blink_gen_b, -- 2, 1, 0, 0); -+ cfg_reg.cfg = _init_sgpio_cfg(1, cache->blink_gen_a, -+ cache->blink_gen_b, 2, 1, 0, 0); -+ -+ _dump_sgpio_hdr("CFG", cfg_reg.hdr); -+ _dump_sgpio_req("CFG", cfg_reg.req); -+ _dump_sgpio_cfg("CFG", cfg_reg.cfg); - -- _dump_cfg_register(&cfg_reg); - return _send_sgpio_register(em_buffer_path, &cfg_reg, sizeof(cfg_reg)); - } - --static void _dump_sgpio_tx(sgpio_tx_t *tx) -+static void _dump_sgpio_tx(const char *type, sgpio_tx_t tx) - { - int i; - -- log_debug("SGPIO TX Register:\n"); -+ log_debug("%s SGPIO TX Register: %08x\n", type, tx); - for (i = 0; i < 4; i++) { - log_debug("\tdrive %d: error %x, locate %x, activity %x\n", i, -- get_error_led(&tx->drive[i]), -- get_locate_led(&tx->drive[i]), -- get_activity_led(&tx->drive[i])); -+ get_error_led(&tx.drive[i]), -+ get_locate_led(&tx.drive[i]), -+ get_activity_led(&tx.drive[i])); - } - } - --static void _dump_tx_register(struct transmit_register *tx_reg) --{ -- uint32_t *reg = (uint32_t *)tx_reg; -- -- log_info("TX Register: %08x %08x %08x %08x", reg[0], reg[1], -- reg[2], reg[3]); -- -- _dump_sgpio_hdr(&tx_reg->hdr); -- _dump_sgpio_req(&tx_reg->req); -- _dump_sgpio_tx(&tx_reg->tx); --} -- - static int _write_tx_register(const char *em_buffer_path, - struct transmit_register *tx_reg) - { -- _init_sgpio_hdr(&tx_reg->hdr, 0, sizeof(*tx_reg)); -- _init_sgpio_req(&tx_reg->req, 0x40, 0x82, SGPIO_REQ_REG_TYPE_TX, 0, 1); -+ tx_reg->hdr = _init_sgpio_hdr(0, sizeof(*tx_reg)); -+ tx_reg->req = _init_sgpio_req(0x40, 0x82, SGPIO_REQ_REG_TYPE_TX, -+ 0, 1); -+ -+ _dump_sgpio_hdr("TX", tx_reg->hdr); -+ _dump_sgpio_req("TX", tx_reg->req); -+ _dump_sgpio_tx("TX", tx_reg->tx); - -- _dump_tx_register(tx_reg); - return _send_sgpio_register(em_buffer_path, tx_reg, sizeof(*tx_reg)); - } - -@@ -538,28 +536,20 @@ static int _init_tx_drive_leds(struct transmit_register *tx_reg, - return init_done; - } - --static void _dump_amd_register(struct amd_register *amd_reg) --{ -- uint32_t *reg = (uint32_t *)amd_reg; -- -- log_info("AMD Register: %08x %08x %08x %08x", reg[0], reg[1], -- reg[2], reg[3]); -- -- _dump_sgpio_hdr(&amd_reg->hdr); -- _dump_sgpio_req(&amd_reg->req); -- _dump_sgpio_amd(&amd_reg->amd); --} -- - static int _write_amd_register(const char *em_buffer_path, - struct amd_drive *drive) - { - struct amd_register amd_reg; - -- _init_sgpio_hdr(&amd_reg.hdr, 0, sizeof(amd_reg)); -- _init_sgpio_req(&amd_reg.req, 0x40, 0x82, SGPIO_REQ_REG_TYPE_AMD, 0, 1); -- _init_sgpio_amd(&amd_reg.amd, drive->initiator, 0, 1, 1); -+ amd_reg.hdr = _init_sgpio_hdr(0, sizeof(amd_reg)); -+ amd_reg.req = _init_sgpio_req(0x40, 0x82, SGPIO_REQ_REG_TYPE_AMD, -+ 0, 1); -+ amd_reg.amd = _init_sgpio_amd(drive->initiator, 0, 1, 1); -+ -+ _dump_sgpio_hdr("AMD", amd_reg.hdr); -+ _dump_sgpio_req("AMD", amd_reg.req); -+ _dump_sgpio_amd("AMD", amd_reg.amd); - -- _dump_amd_register(&amd_reg); - return _send_sgpio_register(em_buffer_path, &amd_reg, sizeof(amd_reg)); - } - diff --git a/SOURCES/0004-dont_build_with_werror.patch b/SOURCES/0004-dont_build_with_werror.patch deleted file mode 100644 index 91848c1..0000000 --- a/SOURCES/0004-dont_build_with_werror.patch +++ /dev/null @@ -1,29 +0,0 @@ -commit e4ee8feed7a2b460bbb202704072c1927015265f -Author: Adrian Bunk -Date: Thu Oct 31 12:28:48 2019 +0200 - - Don't build with -Werror - - New compiler versions might output new warnings by default - (see #47 for an example), which makes -Werror problematic - for distributions. - - The more specific -Werror= settings are usually not a problem. - - The warnings are still shown, but they will no longer break - the build. - - Signed-off-by: Adrian Bunk - -diff --git a/configure.ac b/configure.ac -index 7bc20f8..7e01bd5 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -22,7 +22,6 @@ AX_AM_CFLAGS_ADD([-Werror=format-truncation=1]) - AX_AM_CFLAGS_ADD([-Werror=shift-negative-value]) - AX_AM_CFLAGS_ADD([-Werror=alloca]) - AX_AM_CFLAGS_ADD([-Werror=missing-field-initializers]) --AX_AM_CFLAGS_ADD([-Werror]) - AX_AM_CFLAGS_ADD([-Werror=format-signedness]) - - AC_SUBST([AM_CFLAGS]) diff --git a/SPECS/ledmon.spec b/SPECS/ledmon.spec index e6601c4..00589a9 100644 --- a/SPECS/ledmon.spec +++ b/SPECS/ledmon.spec @@ -1,18 +1,15 @@ Summary: Enclosure LED Utilities Name: ledmon -Version: 0.93 +Version: 0.94 Release: 1%{?dist} License: GPLv2+ Group: Applications/System URL: https://github.com/intel/ledmon Source0: https://github.com/intel/ledmon/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz -Patch1: 0001-ledmon_paths_in_systemd_service_file_are_generated.patch -Patch2: 0002-smp_fix_the_activity_indicator_states.patch -Patch3: 0003-amd_sgpio_correct_use_of_packed_structs.patch -Patch4: 0004-dont_build_with_werror.patch BuildRequires: perl-interpreter perl-podlators BuildRequires: sg3_utils-devel +BuildRequires: pciutils-devel BuildRequires: autoconf, automake # Needed for the udev dependency. BuildRequires: systemd-devel @@ -29,10 +26,6 @@ use this application. %prep %setup -q -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 %build # can't use smp_flags because -j4 makes the build fail @@ -52,6 +45,9 @@ make install INSTALL="%{__install} -p" DESTDIR=$RPM_BUILD_ROOT SBIN_DIR=$RPM_BUI %{_unitdir}/ledmon.service %changelog +* Mon Feb 17 2020 Jan Synáček - 0.94-1 +- update to 0.94 (#1780521) + * Tue Dec 10 2019 Jan Synáček - 0.93-1 - update to 0.93 (#1721928)