From nobody Fri Dec 19 14:24:07 2025 Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 13C4A2F60A2 for ; Wed, 5 Nov 2025 23:47:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.11.138.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762386434; cv=none; b=LMdsuYqw8nPm22gANzkayqoQQkjtexk36bu6lxQxpYYLy6YFBIcjbk2ZwGYxdLIlP8Pb6s3uulib1Kw+QBAm4xwySIYNN1U0gDX8Ewm6YLieCls6cQO3eq+ZGRuiuoFhEF+p2iyXD6ui88X7EWaQ3Y5DUn2ZNvfz1uDf7HatWLM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762386434; c=relaxed/simple; bh=nXovU8Z9lcvw9h3dBvRi7sK4wfZTfh+iEEWHXqhJ3Zs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jqK7OHLoWObZtwf1IVuBbbWKoB3x1y+L428/w7A67JqifJnsIPklZ3SzLRDd+808nBALil2gTeQhIIe0yrK1Wq/I4IzPSem+uKM/13RswE19a7dCN4F8W5dDbUi1KwWC2mtICqGkY/ncPr9gzlzeR2Z2CtFcXF1y2c/CUxWFq3s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sntech.de; spf=pass smtp.mailfrom=sntech.de; dkim=pass (2048-bit key) header.d=sntech.de header.i=@sntech.de header.b=E/MkvX3c; arc=none smtp.client-ip=185.11.138.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sntech.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sntech.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sntech.de header.i=@sntech.de header.b="E/MkvX3c" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sntech.de; s=gloria202408; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-Type; bh=/P2H1HQIzFcvBqE1RaZPIVfxAOIj1n2GfQ8xkB+a48M=; b=E/MkvX3cO8Yvl5KzfQgBkpkWyC soLKyL3dyPD9dDTCbpW/Ww1AA3MWHoaKHUlLSn2HSxo8rBgB6t6JuMR8kZ5Mwob+lgUeR9evaaCjc KdBvNPUA+PDxzwYk8fPPh15ql+iny1SMDIKnbJqkEJISxyLnoY/fgiYmoMRL9onbw+5KeFOi59seP ves8vjIKGkgmD/tCk5eQI0mh1Iz2FgOg9lWEMpdPRP/VIwg8JI0oWaCuFbAY4EBfF1M73OCrYj3/k vEmK6J6Ud+J2rXcnGIWSF3OXsCF93BUNhG/VG228mmbRk0S9msyMR7/zW8v6I4lAH4cRBpGwZ4/WX aUu467fQ==; Received: from i53875bde.versanet.de ([83.135.91.222] helo=phil.fritz.box) by gloria.sntech.de with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1vGnDb-0001Oh-8P; Thu, 06 Nov 2025 00:47:11 +0100 From: Heiko Stuebner To: lee@kernel.org Cc: linux-kernel@vger.kernel.org, heiko@sntech.de Subject: [PATCH v2 1/4] mfd: qnap-mcu: Calculate the checksum on the actual number of bytes received Date: Thu, 6 Nov 2025 00:47:01 +0100 Message-ID: <20251105234704.159381-2-heiko@sntech.de> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20251105234704.159381-1-heiko@sntech.de> References: <20251105234704.159381-1-heiko@sntech.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In the case of an error message, the number of received bytes can be less than originally expected but still contain a valid message. If the transfer itself ended in an error we would exit earlier already. So calculate the checksum on the number of received bytes and not the number of expected bytes. Signed-off-by: Heiko Stuebner --- drivers/mfd/qnap-mcu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/qnap-mcu.c b/drivers/mfd/qnap-mcu.c index 2be429a50611..e3210541ec56 100644 --- a/drivers/mfd/qnap-mcu.c +++ b/drivers/mfd/qnap-mcu.c @@ -175,8 +175,8 @@ int qnap_mcu_exec(struct qnap_mcu *mcu, return -ETIMEDOUT; } =20 - crc =3D qnap_mcu_csum(rx, reply_data_size); - if (crc !=3D rx[reply_data_size]) { + crc =3D qnap_mcu_csum(rx, reply->received - QNAP_MCU_CHECKSUM_SIZE); + if (crc !=3D rx[reply->received - QNAP_MCU_CHECKSUM_SIZE]) { dev_err(&mcu->serdev->dev, "Invalid Checksum received\n"); return -EIO; } --=20 2.47.2 From nobody Fri Dec 19 14:24:07 2025 Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 820872F6190 for ; Wed, 5 Nov 2025 23:47:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.11.138.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762386436; cv=none; b=IfTwbmKKM0mhm9RvBVWn+upvOXu+YM2+c/3RBiiiWzTMs+jKSqVIHDgrLbGmAjWX0Y2iEuRJns14IyoDW00n2PofEh5Qy/02ThQBQOIF+aeZ77bUwAU3VB/EEdZqWakcTxITnvhN9QbSr3Qb2ALKzQCdeePI+uG/6gKSXl73AAM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762386436; c=relaxed/simple; bh=N+Ft/PmrtbS1c2vl4AHC6AfYZVStrjBDS5Fxlyfgs08=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tJZCwAyuCnxwkIQtiBu/2wsPdJ7zNuy/ZFWQ31o02GOBqZu8IKE22dLexBo6/eqX2sUbxr+UREjB0eU/FnH9MRbeRn7NcIi5fHbE0eeRjfU7PwotJHY17CAESPvvRLmIrEEVtOq2sEB+byiqMR1Uoa3V79F/az9cM4Fq6lzGpDg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sntech.de; spf=pass smtp.mailfrom=sntech.de; dkim=pass (2048-bit key) header.d=sntech.de header.i=@sntech.de header.b=gpi5MKkn; arc=none smtp.client-ip=185.11.138.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sntech.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sntech.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sntech.de header.i=@sntech.de header.b="gpi5MKkn" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sntech.de; s=gloria202408; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-Type; bh=nQYxBu/Q09Up2UjAV3Yg5ScyfmPTkQa5TKMKUGdESZo=; b=gpi5MKknn+gBrL08zj1SqDIH4z sw9TovzN3H0DL3Yl+yxAgJpmVa3fytRNsrfDBxFtx+eiIUcs7ASIVpTs6tRyznwZ16lgR+l7AsVcf zyXi1DMm+9W6/wVlOhTLqeM29MawaTFw+D80dF0KOWX7hNk+8wlqAIzsNbwkiJ4f/GtWf8vJUaOsY f5pgCZg0eCm9lE0DJUZrQOrrPWXqAFEo/Q3HeCK/wAXAGhw8leEVtCxr0f/7Myzi31Lw7D7MeicSa mnJ3YZahsG+5KZ1tcFf7uwCexkizWXGrlylTt5GnGvGL6IE0dlxhW036Py3U+2dqtDm0e2tMgA0x8 90cRcvhg==; Received: from i53875bde.versanet.de ([83.135.91.222] helo=phil.fritz.box) by gloria.sntech.de with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1vGnDb-0001Oh-Ey; Thu, 06 Nov 2025 00:47:11 +0100 From: Heiko Stuebner To: lee@kernel.org Cc: linux-kernel@vger.kernel.org, heiko@sntech.de Subject: [PATCH v2 2/4] mfd: qnap-mcu: Use EPROTO in stead of EIO on checksum errors Date: Thu, 6 Nov 2025 00:47:02 +0100 Message-ID: <20251105234704.159381-3-heiko@sntech.de> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20251105234704.159381-1-heiko@sntech.de> References: <20251105234704.159381-1-heiko@sntech.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" EPROTO stands for protocol error and a lot of driver already use it to designate errors in the sent or received data from a peripheral. So use it in the qnap-mcu as well for checksum errors. Signed-off-by: Heiko Stuebner --- drivers/mfd/qnap-mcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/qnap-mcu.c b/drivers/mfd/qnap-mcu.c index e3210541ec56..b4b630f7d413 100644 --- a/drivers/mfd/qnap-mcu.c +++ b/drivers/mfd/qnap-mcu.c @@ -178,7 +178,7 @@ int qnap_mcu_exec(struct qnap_mcu *mcu, crc =3D qnap_mcu_csum(rx, reply->received - QNAP_MCU_CHECKSUM_SIZE); if (crc !=3D rx[reply->received - QNAP_MCU_CHECKSUM_SIZE]) { dev_err(&mcu->serdev->dev, "Invalid Checksum received\n"); - return -EIO; + return -EPROTO; } =20 memcpy(reply_data, rx, reply_data_size); --=20 2.47.2 From nobody Fri Dec 19 14:24:07 2025 Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 820022F618B for ; Wed, 5 Nov 2025 23:47:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.11.138.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762386435; cv=none; b=XQuGE32ZqVwaJ9Out8dYUAUZZQ3te7sloXyj95CijoaLA1OohB+6vcEiTeXi6Z4o1hKqPZ4Z3FwLD5AsjdojtMec3TrRYTD0a7LpPSKygCO/fxvnM5FbiieHDuJBpJyta86MV1UveBjly+xkHyymAxDYl1N/KirMQp16MXBMMHg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762386435; c=relaxed/simple; bh=DY/Ofcn/Ow8r+LCBGOumGnV6d/7pc2frhjwOPeU7DJ0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=o3rVpI2vY5QEdlDt//91p3wX8AQ3zdXg4Kkkw28p/zJU67gef2BJ5/hEM9kZcukW9+SURmCqO64qkOPt8Q6p2QvJQMC7cFbIxgKcJq1wfW4blvANHpuTOKE2vmnMzjWKm8HeUdj/7XToT6gavx6V6snbt6mNFRTngVUHiu8mecg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sntech.de; spf=pass smtp.mailfrom=sntech.de; dkim=pass (2048-bit key) header.d=sntech.de header.i=@sntech.de header.b=iYBwEYxf; arc=none smtp.client-ip=185.11.138.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sntech.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sntech.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sntech.de header.i=@sntech.de header.b="iYBwEYxf" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sntech.de; s=gloria202408; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-Type; bh=YXITm8DEAzGdardV/rwB/49K9rMVAUg6IGseVbSkN+U=; b=iYBwEYxftn0bFpTj0tc/lu2Wa4 N9lUbPwBf5Po5yNqu3bZI0YyvlJ6xyQ8wR6AriFOPJ1ZDsvgPTpgXmgmSG5e5PDakjYjpuhz1XbbD ISy/69nRD1isrbmbBH8j/pehOfnJE9mVjEcyLfMZfqKlomZHNkqY4o7m9MzNEuimGeaS+8H3kZSvR ZqVTzlLWhOOO7QrvNcorVFjQr2go5DwGN76EUgyPW+D6rdQ0nl1/I4wycHpcX/vDz1e1tNvJzMuAZ gqEGJE4l0pc9iI564oZID9MRG+llX3U3cb/tNElzWJgdX076Ze06vmQqfWXEssn6HY/JneORJYco+ hVTUHvpw==; Received: from i53875bde.versanet.de ([83.135.91.222] helo=phil.fritz.box) by gloria.sntech.de with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1vGnDb-0001Oh-OD; Thu, 06 Nov 2025 00:47:11 +0100 From: Heiko Stuebner To: lee@kernel.org Cc: linux-kernel@vger.kernel.org, heiko@sntech.de Subject: [PATCH v2 3/4] mfd: qnap-mcu: Move checksum verification to its own function Date: Thu, 6 Nov 2025 00:47:03 +0100 Message-ID: <20251105234704.159381-4-heiko@sntech.de> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20251105234704.159381-1-heiko@sntech.de> References: <20251105234704.159381-1-heiko@sntech.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" We'll need the checksum check in a second place in the future, so move the verification code to a separate function. Signed-off-by: Heiko Stuebner --- drivers/mfd/qnap-mcu.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/qnap-mcu.c b/drivers/mfd/qnap-mcu.c index b4b630f7d413..cd836bdd44a8 100644 --- a/drivers/mfd/qnap-mcu.c +++ b/drivers/mfd/qnap-mcu.c @@ -78,6 +78,13 @@ static u8 qnap_mcu_csum(const u8 *buf, size_t size) return csum; } =20 +static bool qnap_mcu_verify_checksum(const u8 *buf, size_t size) +{ + u8 crc =3D qnap_mcu_csum(buf, size - QNAP_MCU_CHECKSUM_SIZE); + + return crc =3D=3D buf[size - QNAP_MCU_CHECKSUM_SIZE]; +} + static int qnap_mcu_write(struct qnap_mcu *mcu, const u8 *data, u8 data_si= ze) { unsigned char tx[QNAP_MCU_TX_BUFFER_SIZE]; @@ -150,7 +157,6 @@ int qnap_mcu_exec(struct qnap_mcu *mcu, size_t length =3D reply_data_size + QNAP_MCU_CHECKSUM_SIZE; struct qnap_mcu_reply *reply =3D &mcu->reply; int ret =3D 0; - u8 crc; =20 if (length > sizeof(rx)) { dev_err(&mcu->serdev->dev, "expected data too big for receive buffer"); @@ -175,8 +181,7 @@ int qnap_mcu_exec(struct qnap_mcu *mcu, return -ETIMEDOUT; } =20 - crc =3D qnap_mcu_csum(rx, reply->received - QNAP_MCU_CHECKSUM_SIZE); - if (crc !=3D rx[reply->received - QNAP_MCU_CHECKSUM_SIZE]) { + if (!qnap_mcu_verify_checksum(rx, reply->received)) { dev_err(&mcu->serdev->dev, "Invalid Checksum received\n"); return -EPROTO; } --=20 2.47.2 From nobody Fri Dec 19 14:24:07 2025 Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7E4AC2F6180 for ; Wed, 5 Nov 2025 23:47:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.11.138.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762386435; cv=none; b=VzsNxM2zLNhvO9IA9iDzKJL0xDsAAJ1RyVDM/6cwK76ihwmJiO+cwwmk1TyZu4ahgA5WqCurzbcAyanucOYAS7ojPBIE7VFTLoxaJIR6Tzn42dsIHlOS9Fz/7C2ozPoXg1o7ulCSsFfLU+xjjnS7xcjz7yImnr7x5HoFeYR8mJY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762386435; c=relaxed/simple; bh=Sd+NKy39TSbX+RkKmGRiW1DJIVJLykXwHgc6FJ8Ct8E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rpMkyaCJySRg7a7mCqLsDk1q6comd6wlVKBvy9WoAu/U4ipNRQH0H3THwdExIZXzDoPBU+fPozqgv6imXElu6DTYu2oqapgUoS8vAZ2T6hYFRwwaQP6FFOBeqterwPuJIgUnN5a4FxSsGFdpnWcZpkpdckIaVlhWX5KA9hco3BQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sntech.de; spf=pass smtp.mailfrom=sntech.de; dkim=pass (2048-bit key) header.d=sntech.de header.i=@sntech.de header.b=2vfv8yg6; arc=none smtp.client-ip=185.11.138.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=sntech.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=sntech.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sntech.de header.i=@sntech.de header.b="2vfv8yg6" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sntech.de; s=gloria202408; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-Type; bh=C75UguP6CTqG3pj4T88TFnBval75AVF75tb86M6LdKU=; b=2vfv8yg6OfduldmclbUTupJk9b VIqviedoutvc5ps1M8u8IuNC0ZGAULCeaXYNqOFezVn+N5Jf+3z+/K7qK86jdNgIIZbFtSoi9zWPu mbe+7sTchTS8HOHQbczq+cKubgZFdx2GQP0pLYYKiOjBdlbJFZ+bSApt4nIcPZDq0Nmeeq4Zd82Of pD2/cDrX9RVNzQSSKHeHBRFuWseWwKXG7gDnWjXTr5pqRXQaEcoXBjA7K3/hvbe0TSHHQHwb4A615 SVFgx/S4mVM4RmpKF0aNM6z42cz8u08t8VYh9Y65ef2mDrX88yn42SKjexx4fSZGfV4bkhaoHMoV/ qDAVrFVQ==; Received: from i53875bde.versanet.de ([83.135.91.222] helo=phil.fritz.box) by gloria.sntech.de with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1vGnDb-0001Oh-Ur; Thu, 06 Nov 2025 00:47:12 +0100 From: Heiko Stuebner To: lee@kernel.org Cc: linux-kernel@vger.kernel.org, heiko@sntech.de Subject: [PATCH v2 4/4] mfd: qnap-mcu: Add proper error handling for command errors Date: Thu, 6 Nov 2025 00:47:04 +0100 Message-ID: <20251105234704.159381-5-heiko@sntech.de> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20251105234704.159381-1-heiko@sntech.de> References: <20251105234704.159381-1-heiko@sntech.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Further investigation revealed that the MCU in QNAP devices may return two error states. One "@8" for a checksum error in the submitted command and one "@9" for any generic (and sadly unspecified) error. These error codes with 2 data character can of course also be shorter then the expected reply length for the submitted command, so we'll need to check the received data for error codes and exit the receive portion early in that case. Signed-off-by: Heiko Stuebner --- drivers/mfd/qnap-mcu.c | 65 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/qnap-mcu.c b/drivers/mfd/qnap-mcu.c index cd836bdd44a8..8c5eb4a72829 100644 --- a/drivers/mfd/qnap-mcu.c +++ b/drivers/mfd/qnap-mcu.c @@ -19,6 +19,7 @@ /* The longest command found so far is 5 bytes long */ #define QNAP_MCU_MAX_CMD_SIZE 5 #define QNAP_MCU_MAX_DATA_SIZE 36 +#define QNAP_MCU_ERROR_SIZE 2 #define QNAP_MCU_CHECKSUM_SIZE 1 =20 #define QNAP_MCU_RX_BUFFER_SIZE \ @@ -103,6 +104,47 @@ static int qnap_mcu_write(struct qnap_mcu *mcu, const = u8 *data, u8 data_size) return serdev_device_write(mcu->serdev, tx, length, HZ); } =20 +static bool qnap_mcu_is_error_msg(size_t size) { + return (size =3D=3D QNAP_MCU_ERROR_SIZE + QNAP_MCU_CHECKSUM_SIZE); +} + +static bool qnap_mcu_reply_is_generic_error(unsigned char *buf, size_t siz= e) +{ + if (!qnap_mcu_is_error_msg(size)) + return false; + + if (buf[0] =3D=3D '@' && buf[1] =3D=3D '9') + return true; + + return false; +} + +static bool qnap_mcu_reply_is_checksum_error(unsigned char *buf, size_t si= ze) +{ + if (!qnap_mcu_is_error_msg(size)) + return false; + + if (buf[0] =3D=3D '@' && buf[1] =3D=3D '8') + return true; + + return false; +} + +static bool qnap_mcu_reply_is_any_error(struct qnap_mcu *mcu, unsigned cha= r *buf, size_t size) +{ + if (qnap_mcu_reply_is_generic_error(buf, size)) { + dev_err(&mcu->serdev->dev, "Controller sent generic error response\n"); + return true; + } + + if (qnap_mcu_reply_is_checksum_error(buf, size)) { + dev_err(&mcu->serdev->dev, "Controller received invalid checksum for the= command\n"); + return true; + } + + return false; +} + static size_t qnap_mcu_receive_buf(struct serdev_device *serdev, const u8 = *buf, size_t size) { struct device *dev =3D &serdev->dev; @@ -136,6 +178,24 @@ static size_t qnap_mcu_receive_buf(struct serdev_devic= e *serdev, const u8 *buf, } } =20 + /* + * We received everything the uart had to offer for now. + * This could mean that either the uart will send more in a 2nd + * receive run, or that the MCU cut the reply short because it + * sent an error code instead of the expected reply. + * + * So check if the received data has the correct size for an error + * reply and if it matches, is an actual error code. + */ + if (qnap_mcu_is_error_msg(reply->received) && + qnap_mcu_verify_checksum(reply->data, reply->received) && + qnap_mcu_reply_is_any_error(mcu, reply->data, reply->received)) { + /* The reply was an error code, we're done */ + reply->length =3D 0; + + complete(&reply->done); + } + /* * The only way to get out of the above loop and end up here * is through consuming all of the supplied data, so here we @@ -182,10 +242,13 @@ int qnap_mcu_exec(struct qnap_mcu *mcu, } =20 if (!qnap_mcu_verify_checksum(rx, reply->received)) { - dev_err(&mcu->serdev->dev, "Invalid Checksum received\n"); + dev_err(&mcu->serdev->dev, "Invalid Checksum received from controller\n"= ); return -EPROTO; } =20 + if (qnap_mcu_reply_is_any_error(mcu, rx, reply->received)) + return -EPROTO; + memcpy(reply_data, rx, reply_data_size); =20 return 0; --=20 2.47.2