From nobody Wed Dec 17 14:24:40 2025 Received: from mo4-p02-ob.smtp.rzone.de (mo4-p02-ob.smtp.rzone.de [85.215.255.82]) (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 3A4F82FCC01; Fri, 7 Nov 2025 23:08:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=85.215.255.82 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762556917; cv=pass; b=JBKi2wWBh5dRCm45IjTlysBaZkC+fiOdUp1pck7SP4Jfci2hBRRrPRVLQESfSOT+UDLRAGnDJJPBeeajednU5OZs7QhitAawB/zIScu2R59AXvfOqqbxSHDm1k+pYSIAnOt6vEtedkUgn+GvMTlqT8GS+QYMx+T5FNg3TpC96Ak= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762556917; c=relaxed/simple; bh=egoiJtwPjZGIOorc5g5Af/WNfUoMyIkVsLrAX+1kAdU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=fJPtqYfQBrmOoNIj7l3LmyB+jI7Guqzz3mtLtitPsBEwDlDKqSY2EgWAH9ngwGG/CTrS8QgEBECfoc2900SoB5NtQ7J3cOwVft9h3ga3gt6rFRXv7Umy8ZHpQ5zQSGhaH0T3+f+kz3aCAQRYInUCGrYRQrdOlSFgSdMxZIxh0vo= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iokpp.de; spf=none smtp.mailfrom=iokpp.de; dkim=pass (2048-bit key) header.d=iokpp.de header.i=@iokpp.de header.b=RxuZyXCy; dkim=permerror (0-bit key) header.d=iokpp.de header.i=@iokpp.de header.b=0PeoL4oc; arc=pass smtp.client-ip=85.215.255.82 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iokpp.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=iokpp.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=iokpp.de header.i=@iokpp.de header.b="RxuZyXCy"; dkim=permerror (0-bit key) header.d=iokpp.de header.i=@iokpp.de header.b="0PeoL4oc" ARC-Seal: i=1; a=rsa-sha256; t=1762556733; cv=none; d=strato.com; s=strato-dkim-0002; b=bn7gRN6N9076q8VlX6FhFj3J2oEp2fRkbLXGPFCU6PavVDcKyGo8kofRpwXwhs62mN YWiyaua4bVh0Ui0EiGYKM3wh3jzsrF7fRm7oS4n+P9pU/Oaaxrmg9weX7VP5gvKxDND7 qUpdD/t5sIsHQw57bNCqvmtelS38DMNhI1Ya9ZhVdi6t8o6uwUbZXQ+WdI8EcG3o/SPU zLbwGmWnc4pepqaAV9GldNBwabpXfQybRavms98Rskod0w/VSmFKMi3KV4AIaptVoUWL KGKgkS4SF60ULaJi9KQotRUK20JgJiecf9BIwF0ZPzEYQ3eYCOBRaZECpGx2S5r+kYqG rn7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1762556733; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=n8p4GaEJUPyQ5WHhjeoHGpZO1UdnQvpCL1hsdbJ9Isw=; b=XutjK/c4Bu236dxb8Q9Oo/y13HAk+16jKC/ttTlDxjD5t3vWsfd+Mcv0tWy4FLwGOf NIbhFcE7SKsnSImHMd3VQ1AtB9Pj4D3IeduJupsVMBe6DHQ6X3ZTG0oNozga35MkIheN pYsLEliKJ6hss8CM/FbcDR/t/uLnwm5X2LINZdNgaedE/6CboCfCahaRBVKJq2icl6Gx 7znxMv6XS3JkGIpVc/XGdCVVuKSsWUP+gF7RcsTcyGfJzLJkryHHGoGvxb8Oi6XjxCEP 68FhQKNSZKKos1KHyRYHR5G3pr9ChVJW+L+Z8YlaRc+YpNhusMmPdebHEwuv8XW0bCwS vLzg== ARC-Authentication-Results: i=1; strato.com; arc=none; dkim=none X-RZG-CLASS-ID: mo02 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1762556733; s=strato-dkim-0002; d=iokpp.de; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=n8p4GaEJUPyQ5WHhjeoHGpZO1UdnQvpCL1hsdbJ9Isw=; b=RxuZyXCymjI0GLWS5o00cpWEcqPyJRLIofP6OdVqoKQpQA578P4kAR63CW4DoyOU0N 0rQ5rE7nXGddeSy07yAX7uJ29Csb1xm4k/3SQuHsaUN05itNT3dZNZt1ZKeSee2f0uMx am2G1ikQzyQhm+rEuh+hAFhd1wqOVH3cqZ9zHHZwEQQ9RS+TGJpMmbm12bb7gx7kqr/0 GO7+N4LhUdL58i0FVafSPiS56yB7WMTIefp0fkkzduzNWqEBx5cBy7A+SVJcm1NfEcGJ 2Ce8x7p3zC6ls+vOj23dw0VBjZOsfpuEnZDxQ2BGJEFOx9qRVYSQRKcyQD/tgHNjRK5L OuwA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; t=1762556733; s=strato-dkim-0003; d=iokpp.de; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=n8p4GaEJUPyQ5WHhjeoHGpZO1UdnQvpCL1hsdbJ9Isw=; b=0PeoL4ocklz0+TK2H3NG35dks7klZ724DJ7oo1hVmrE3gEfng6ZQdVKzH2/oqPIkF3 bAkKA7ZreGGGot9dChDw== X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSfNuhhDSDt3O256fJ4HnWXON1RCk6IvFmDk3pfNYaBAA9V8VVg9RNybYRrdPP/A=" Received: from Munilab01-lab.speedport.ip by smtp.strato.de (RZmta 54.0.0 AUTH) with ESMTPSA id zd76761A7N5WNXX (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Sat, 8 Nov 2025 00:05:32 +0100 (CET) From: Bean Huo To: avri.altan@wdc.com, bvanassche@acm.org, alim.akhtar@samsung.com, jejb@linux.ibm.com, martin.petersen@oracle.com, can.guo@oss.qualcomm.com, ulf.hansson@linaro.org, beanhuo@micron.com, jens.wiklander@linaro.org Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Avri Altman Subject: [PATCH v7 1/3] scsi: ufs: core: Convert string descriptor format macros to enum Date: Sat, 8 Nov 2025 00:05:16 +0100 Message-Id: <20251107230518.4060231-2-beanhuo@iokpp.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251107230518.4060231-1-beanhuo@iokpp.de> References: <20251107230518.4060231-1-beanhuo@iokpp.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" From: Bean Huo Convert SD_ASCII_STD and SD_RAW from boolean macros to enum values for impr= oved code readability. This makes ufshcd_read_string_desc() calls self-documenti= ng by using explicit enum values instead of true/false. Move the ufshcd_read_string_desc() declaration from include/ufs/ufshcd.h to drivers/ufs/core/ufshcd-priv.h since this function is not exported. Co-developed-by: Bart Van Assche Signed-off-by: Bart Van Assche Suggested-by: Avri Altman Signed-off-by: Bean Huo --- drivers/ufs/core/ufshcd-priv.h | 14 ++++++++++---- drivers/ufs/core/ufshcd.c | 8 +++----- include/ufs/ufshcd.h | 4 ---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h index 1f0d38aa37f9..f3eeaf45cfdb 100644 --- a/drivers/ufs/core/ufshcd-priv.h +++ b/drivers/ufs/core/ufshcd-priv.h @@ -80,11 +80,17 @@ int ufshcd_try_to_abort_task(struct ufs_hba *hba, int t= ag); void ufshcd_release_scsi_cmd(struct ufs_hba *hba, struct ufshcd_lrb *lrbp); =20 -#define SD_ASCII_STD true -#define SD_RAW false -int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, - u8 **buf, bool ascii); +/** + * enum ufs_descr_fmt - UFS string descriptor format + * @SD_RAW: Raw UTF-16 format + * @SD_ASCII_STD: Convert to null-terminated ASCII string + */ +enum ufs_descr_fmt { + SD_RAW =3D 0, + SD_ASCII_STD =3D 1, +}; =20 +int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, u8 **buf, = enum ufs_descr_fmt fmt); int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd); int ufshcd_send_bsg_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_c= md); =20 diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index fc4d1b6576dc..35ab61aefb72 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -3774,16 +3774,14 @@ static inline char ufshcd_remove_non_printable(u8 c= h) * @desc_index: descriptor index * @buf: pointer to buffer where descriptor would be read, * the caller should free the memory. - * @ascii: if true convert from unicode to ascii characters - * null terminated string. + * @fmt: if %SD_ASCII_STD, convert from UTF-16 to ASCII * * Return: * * string size on success. * * -ENOMEM: on allocation failure * * -EINVAL: on a wrong parameter */ -int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, - u8 **buf, bool ascii) +int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, u8 **buf, = enum ufs_descr_fmt fmt) { struct uc_string_id *uc_str; u8 *str; @@ -3812,7 +3810,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 d= esc_index, goto out; } =20 - if (ascii) { + if (fmt =3D=3D SD_ASCII_STD) { ssize_t ascii_len; int i; /* remove header and divide by 2 to move from UTF16 to UTF8 */ diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 00152e135fc9..4fb1998b84cf 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -1432,10 +1432,6 @@ static inline int ufshcd_disable_host_tx_lcc(struct = ufs_hba *hba) void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit); void ufshcd_fixup_dev_quirks(struct ufs_hba *hba, const struct ufs_dev_quirk *fixups); -#define SD_ASCII_STD true -#define SD_RAW false -int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, - u8 **buf, bool ascii); =20 void ufshcd_hold(struct ufs_hba *hba); void ufshcd_release(struct ufs_hba *hba); --=20 2.34.1 From nobody Wed Dec 17 14:24:40 2025 Received: from mo4-p02-ob.smtp.rzone.de (mo4-p02-ob.smtp.rzone.de [85.215.255.82]) (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 A28FF2E06EF; Fri, 7 Nov 2025 23:05:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=85.215.255.82 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762556746; cv=pass; b=ofnbnoC/lhydni/xtURYR0BG1gs5LBfVvtl5cMq7KA04qbyqky/B6S2Vw09juvS0UBvCfmBFLNc9w1fmNJnOqtvZ8IbGAdrcPil1WWySuqL8JGqfUR3BQx0Ekvb1XkPj2FMe5QKFxjwpJBpoJUjS8BlgMAGqqN/eMG1hhUUkL9Q= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762556746; c=relaxed/simple; bh=4VP0VoxuU1WjanN31pq6WRGAf86fZSl8C0HU8Gx6hGw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=PrdtkymMxp+YunOFVmkj09WXlKAqHwgcFctmy+o+ET2+tQjePqXhE/cVTa1HBscADvwQ+RsBabWqVTtdsjBtGUYeX/7regX1N90YbkfNa0VsLKAZ6gMGnpnAszXRJHO5LFu5lilm6XjjVcxhG7My1UtNDsCbzKe6nYLdDTDjGRE= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iokpp.de; spf=none smtp.mailfrom=iokpp.de; dkim=pass (2048-bit key) header.d=iokpp.de header.i=@iokpp.de header.b=W5KwJe6h; dkim=permerror (0-bit key) header.d=iokpp.de header.i=@iokpp.de header.b=9zyeZHi4; arc=pass smtp.client-ip=85.215.255.82 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iokpp.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=iokpp.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=iokpp.de header.i=@iokpp.de header.b="W5KwJe6h"; dkim=permerror (0-bit key) header.d=iokpp.de header.i=@iokpp.de header.b="9zyeZHi4" ARC-Seal: i=1; a=rsa-sha256; t=1762556733; cv=none; d=strato.com; s=strato-dkim-0002; b=V06V5FVJXTz12PRqhtVu8Hgvapv7AtvKWxGXHN0xxC3H9kBkVua1PyKY7cU/jixmXf mjyaO/IfJaGM1WTTGlQLqOTwQNHcjav2ajBIpFrzUcP1/qrX2w/vpnOp9jcg/Ze3lomL c0I79Ol5h0r6UpM2cJVxOgRQOGokvMnpi5K38prUsmQYdRJXtvU/L2zHZecugxyO4Sn+ cwNnhhkQzDZAZvSivuc1l4iNCb9eMJJJ6AKufycwvje70+dyh7bJ8s6noRVM4WU7XozF 5MxaHfAG8G2X/ItH5PAqVDrU+IZnNuJY3IP/VEEcJz9ENMeRfkUO7nPMmDn14op0c4w+ kWng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1762556733; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=tsXJHzfZt/H/3JMg3mtg3cFRvL9N2GF3FO/sMVeQIoU=; b=PWCZc8ENzLixoYDJstU7y+qm+vICkOr2OsEvTdBWltrE2YU9VRp4jIcnmzfAnKKLgS 7dKN7qe6rzaxfFcbALEggi6zO4DRu23F/P/NyCzM7iimrsWt4/leRUGIpz3WbFnkhcuP Ra14hMFRTlhYYGTyK0so5ADcz+ByErvBSpipZ5nAIk3khWI7cCeLx/kpznv8H201oEim Mc5VX7IwrvMfnWYYw/olbT2W8/TuhNCkxuCHfF78ou+Pl50ciohlurgxdSHyFjzRLCCL sN/9V1IAjnK+c40CfyOANR7kCMY7wXVxLVZ7GOpWB/dmgW7r0psd5niUX4DU8XRbSEk/ QB5g== ARC-Authentication-Results: i=1; strato.com; arc=none; dkim=none X-RZG-CLASS-ID: mo02 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1762556733; s=strato-dkim-0002; d=iokpp.de; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=tsXJHzfZt/H/3JMg3mtg3cFRvL9N2GF3FO/sMVeQIoU=; b=W5KwJe6hLtfhAQr88T9fErnjNP4pa2e0Si4kTNlJTptN+ZaaHcW68hTFBcwJ+uWibE a9KzhxV6iO9XS/cjiD/sOUsRfZ8Y7ATHR3PJo6cjlpcWkzXtBZ7D/35Ab9MVNuwi5AL3 NDuV+X8LnaPlQJC3Pm+uL8qKA3lqOOQbmM+EQRGBmMn47nCGZEJ4pzYcaXQKXHPixCzU rCVGywTxNvjEupLkdiMYThoX2tUBhkTCXBtfSYRo82pZmL9oluPYm50J7V6xyl6anmiX x/mYMk2m0AlRbtOFAeKgo+57N50xLgdtowBGl2VSN+8ohfKxcdFQY67871o53fX7z90x c8XA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; t=1762556733; s=strato-dkim-0003; d=iokpp.de; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=tsXJHzfZt/H/3JMg3mtg3cFRvL9N2GF3FO/sMVeQIoU=; b=9zyeZHi4IqLONr7tl6l19h1GlBNekH+e25Gnr/uLLGIUfpIES1X/RgsG/SgRIUJeYM GwuelZVQC9wnLMu5aVBw== X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSfNuhhDSDt3O256fJ4HnWXON1RCk6IvFmDk3pfNYaBAA9V8VVg9RNybYRrdPP/A=" Received: from Munilab01-lab.speedport.ip by smtp.strato.de (RZmta 54.0.0 AUTH) with ESMTPSA id zd76761A7N5XNXY (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Sat, 8 Nov 2025 00:05:33 +0100 (CET) From: Bean Huo To: avri.altan@wdc.com, bvanassche@acm.org, alim.akhtar@samsung.com, jejb@linux.ibm.com, martin.petersen@oracle.com, can.guo@oss.qualcomm.com, ulf.hansson@linaro.org, beanhuo@micron.com, jens.wiklander@linaro.org Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Avri Altman Subject: [PATCH v7 2/3] scsi: ufs: core: fix incorrect buffer duplication in ufshcd_read_string_desc() Date: Sat, 8 Nov 2025 00:05:17 +0100 Message-Id: <20251107230518.4060231-3-beanhuo@iokpp.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251107230518.4060231-1-beanhuo@iokpp.de> References: <20251107230518.4060231-1-beanhuo@iokpp.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" From: Bean Huo The function ufshcd_read_string_desc() was duplicating memory starting from the beginning of struct uc_string_id, which included the length and type fields. As a result, the allocated buffer contained unwanted metadata in addition to the string itself. The correct behavior is to duplicate only the Unicode character array in the structure. Update the code so that only the actual string content is copied into the new buffer. Fixes: 5f57704dbcfe ("scsi: ufs: Use kmemdup in ufshcd_read_string_desc()") Reviewed-by: Avri Altman Reviewed-by: Bart Van Assche Signed-off-by: Bean Huo --- drivers/ufs/core/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 35ab61aefb72..a5849e0c6c35 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -3836,7 +3836,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 d= esc_index, u8 **buf, enum u str[ret++] =3D '\0'; =20 } else { - str =3D kmemdup(uc_str, uc_str->len, GFP_KERNEL); + str =3D kmemdup(uc_str->uc, uc_str->len, GFP_KERNEL); if (!str) { ret =3D -ENOMEM; goto out; --=20 2.34.1 From nobody Wed Dec 17 14:24:40 2025 Received: from mo4-p02-ob.smtp.rzone.de (mo4-p02-ob.smtp.rzone.de [85.215.255.84]) (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 9A5DA6A33B; Fri, 7 Nov 2025 23:05:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=85.215.255.84 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762556747; cv=pass; b=d6kmyTuMYLvMMWprCE7y/GXF5na0HNE/9F1/flrQ+O/L8XvWPqLKuThtvokeOUDmDUwrxg4m6OyNwGyXksnH5Rd/6O8g+e9G7wzX9eC8SN8goVX1qAPqLX8RKDE1qSbUvV8g6CFpQFZp7IovxfG11+ZrOJ8wuro6gbBNhdaQ5D0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762556747; c=relaxed/simple; bh=i9qOhreSZuRFagFwl1PIkgZodbIFy7Z61i/ntKwlwRU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=SVrFNpNGurSeM+thEV9hsIwnrWE5gje1h//ivyxO1GhdYXvZjMaEq/WVo6LT633BGGFm011i+i06wq3uMpU361uw0swAicK+lhQVlpsON2UojZiIj5zDjZVSzxYHx2xlX0fle3i3AZ9qB66+KtUipGtf94Z+up7RSEJbxwUXDa4= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iokpp.de; spf=none smtp.mailfrom=iokpp.de; dkim=pass (2048-bit key) header.d=iokpp.de header.i=@iokpp.de header.b=BnQd/YnH; dkim=permerror (0-bit key) header.d=iokpp.de header.i=@iokpp.de header.b=W1T9R7tx; arc=pass smtp.client-ip=85.215.255.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=iokpp.de Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=iokpp.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=iokpp.de header.i=@iokpp.de header.b="BnQd/YnH"; dkim=permerror (0-bit key) header.d=iokpp.de header.i=@iokpp.de header.b="W1T9R7tx" ARC-Seal: i=1; a=rsa-sha256; t=1762556734; cv=none; d=strato.com; s=strato-dkim-0002; b=g1EGx7rFKrOQamIAimQyw4bKvGU+ATHvyZtlwLpwIKJRAC//kSUmku0duNgvApQhoB pbQuI0McU9jMtUsEBsxOIungNUHdRtFAz97bci81w5pnD/laAIN+w41cje31ZJgIUDZ0 CTzVJ8D7tsMoXCg+/V9nuny1bdHT3U2jbLvT7cjMQzTYjYTLhuBZOY3fuCsXKfiiTj8k HwQJIwOiOxmyepXApWMFDK7Bd6E7sLdDo0cOJkaGaxL/tqFpolgvMCTQvPfhvZ3f0/1l geXKylrQBiO71kEzyfWjved8ahgLskvhGAxSrKR9y+OVVLTMQ1ioqTqZvalA9g9gNcqo bwBg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1762556734; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=PFfRN50PF6ewDfiPBtJMcvNtY6ge0bLXI8Dxmyf6agk=; b=cJcNckDTzrJAmwuKOgA72YWVz4X1v6S5y6tAYEEXomrvS62T1diRQGCkTz/88RwgBA g1HC55XlZ4yelqPKMXo0SH6qTqindKnGHZZUJOgcz40sykE1QdGs/vqHEx6cJramrVP/ Q4d7nxBdQeyIJUOEtU+f4Yez0f4u9bXnD9mbqqzjK2++IcB7x6yntX+mevkoFfLXnGe2 3EVO/7+43+6b9xScgQgt88CaJc+WpvtuJ1VWEyIoCla7qEI+Zq9eK/RvmEr1Cal6+8/J U6nH2N0zgTq6Wt7pUMg7cM9U7HkZ6xb2cblawtVAy6cpddfjTBd9598G/p01U1UOTdBf fuzA== ARC-Authentication-Results: i=1; strato.com; arc=none; dkim=none X-RZG-CLASS-ID: mo02 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1762556734; s=strato-dkim-0002; d=iokpp.de; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=PFfRN50PF6ewDfiPBtJMcvNtY6ge0bLXI8Dxmyf6agk=; b=BnQd/YnHSMhSn032YY5v4eAt/kRxrkDLSsCKpOvemkCAhIpb43VtAw0RvEeUze3jz5 4j5KGD96ZG4qYlB4ncm0uM+YR/KWzRFubHsPcmBPz7c1dXIw3OCsV7WKW3orlU8+xKeQ LQQHt3MggkRFTv1wBTzONB5zkMWAsHJqVCQncwRiohyYty+tzPk8Bp1L9PUl7ygoKS1Z NY5GiSaF9ac0Au1Mh63TNebWM3M3zcYOli48Ef46JVEivREOaCXb+4blE3npDNnPzRnU LpvJBEarwQUVVMj3zec7DgM+867EZwOZcha4lF9Ai/6QoWIeHKqsekEu6f99fAv/2zjI GxYA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; t=1762556734; s=strato-dkim-0003; d=iokpp.de; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=PFfRN50PF6ewDfiPBtJMcvNtY6ge0bLXI8Dxmyf6agk=; b=W1T9R7tx/3KvV3hZA7EUH+IzAis5pEK6UYMTC+V+brMSBbupFiuRme0dfHFYHwSBk7 uhfKj0nOmTpKioDtFaCw== X-RZG-AUTH: ":LmkFe0i9dN8c2t4QQyGBB/NDXvjDB6pBSfNuhhDSDt3O256fJ4HnWXON1RCk6IvFmDk3pfNYaBAA9V8VVg9RNybYRrdPP/A=" Received: from Munilab01-lab.speedport.ip by smtp.strato.de (RZmta 54.0.0 AUTH) with ESMTPSA id zd76761A7N5XNXZ (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Sat, 8 Nov 2025 00:05:33 +0100 (CET) From: Bean Huo To: avri.altan@wdc.com, bvanassche@acm.org, alim.akhtar@samsung.com, jejb@linux.ibm.com, martin.petersen@oracle.com, can.guo@oss.qualcomm.com, ulf.hansson@linaro.org, beanhuo@micron.com, jens.wiklander@linaro.org Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Avri Altman Subject: [PATCH v7 3/3] scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices Date: Sat, 8 Nov 2025 00:05:18 +0100 Message-Id: <20251107230518.4060231-4-beanhuo@iokpp.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251107230518.4060231-1-beanhuo@iokpp.de> References: <20251107230518.4060231-1-beanhuo@iokpp.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" From: Bean Huo This patch adds OP-TEE based RPMB support for UFS devices. This enables sec= ure RPMB operations on UFS devices through OP-TEE, providing the same functiona= lity available for eMMC devices and extending kernel-based secure storage suppor= t to UFS-based systems. Benefits of OP-TEE based RPMB implementation: - Eliminates dependency on userspace supplicant for RPMB access - Enables early boot secure storage access (e.g., fTPM, secure UEFI variabl= es) - Provides kernel-level RPMB access as soon as UFS driver is initialized - Removes complex initramfs dependencies and boot ordering requirements - Ensures reliable and deterministic secure storage operations - Supports both built-in and modular fTPM configurations Co-developed-by: Can Guo Signed-off-by: Can Guo Reviewed-by: Avri Altman Reviewed-by: Bart Van Assche Signed-off-by: Bean Huo --- drivers/misc/Kconfig | 2 +- drivers/ufs/core/Makefile | 1 + drivers/ufs/core/ufs-rpmb.c | 254 +++++++++++++++++++++++++++++++++ drivers/ufs/core/ufshcd-priv.h | 13 ++ drivers/ufs/core/ufshcd.c | 86 ++++++++++- include/ufs/ufs.h | 5 + include/ufs/ufshcd.h | 8 +- 7 files changed, 362 insertions(+), 7 deletions(-) create mode 100644 drivers/ufs/core/ufs-rpmb.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b9c11f67315f..9d1de68dee27 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -106,7 +106,7 @@ config PHANTOM =20 config RPMB tristate "RPMB partition interface" - depends on MMC + depends on MMC || SCSI_UFSHCD help Unified RPMB unit interface for RPMB capable devices such as eMMC and UFS. Provides interface for in-kernel security controllers to access diff --git a/drivers/ufs/core/Makefile b/drivers/ufs/core/Makefile index cf820fa09a04..51e1867e524e 100644 --- a/drivers/ufs/core/Makefile +++ b/drivers/ufs/core/Makefile @@ -2,6 +2,7 @@ =20 obj-$(CONFIG_SCSI_UFSHCD) +=3D ufshcd-core.o ufshcd-core-y +=3D ufshcd.o ufs-sysfs.o ufs-mcq.o +ufshcd-core-$(CONFIG_RPMB) +=3D ufs-rpmb.o ufshcd-core-$(CONFIG_DEBUG_FS) +=3D ufs-debugfs.o ufshcd-core-$(CONFIG_SCSI_UFS_BSG) +=3D ufs_bsg.o ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO) +=3D ufshcd-crypto.o diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c new file mode 100644 index 000000000000..ffad049872b9 --- /dev/null +++ b/drivers/ufs/core/ufs-rpmb.c @@ -0,0 +1,254 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * UFS OP-TEE based RPMB Driver + * + * Copyright (C) 2025 Micron Technology, Inc. + * Copyright (C) 2025 Qualcomm Technologies, Inc. + * + * Authors: + * Bean Huo + * Can Guo + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ufshcd-priv.h" + +#define UFS_RPMB_SEC_PROTOCOL 0xEC /* JEDEC UFS application */ +#define UFS_RPMB_SEC_PROTOCOL_ID 0x01 /* JEDEC UFS RPMB protocol ID, CDB b= yte3 */ + +static const struct bus_type ufs_rpmb_bus_type =3D { + .name =3D "ufs_rpmb", +}; + +/* UFS RPMB device structure */ +struct ufs_rpmb_dev { + u8 region_id; + struct device dev; + struct rpmb_dev *rdev; + struct ufs_hba *hba; + struct list_head node; +}; + +static int ufs_sec_submit(struct ufs_hba *hba, u16 spsp, void *buffer, siz= e_t len, bool send) +{ + struct scsi_device *sdev =3D hba->ufs_rpmb_wlun; + u8 cdb[12] =3D { }; + + cdb[0] =3D send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN; + cdb[1] =3D UFS_RPMB_SEC_PROTOCOL; + put_unaligned_be16(spsp, &cdb[2]); + put_unaligned_be32(len, &cdb[6]); + + return scsi_execute_cmd(sdev, cdb, send ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, + buffer, len, /*timeout=3D*/30 * HZ, 0, NULL); +} + +/* UFS RPMB route frames implementation */ +static int ufs_rpmb_route_frames(struct device *dev, u8 *req, unsigned int= req_len, u8 *resp, + unsigned int resp_len) +{ + struct ufs_rpmb_dev *ufs_rpmb =3D dev_get_drvdata(dev); + struct rpmb_frame *frm_out =3D (struct rpmb_frame *)req; + bool need_result_read =3D true; + u16 req_type, protocol_id; + struct ufs_hba *hba; + int ret; + + if (!ufs_rpmb) { + dev_err(dev, "Missing driver data\n"); + return -ENODEV; + } + + hba =3D ufs_rpmb->hba; + + req_type =3D be16_to_cpu(frm_out->req_resp); + + switch (req_type) { + case RPMB_PROGRAM_KEY: + if (req_len !=3D sizeof(struct rpmb_frame) || resp_len !=3D sizeof(struc= t rpmb_frame)) + return -EINVAL; + break; + case RPMB_GET_WRITE_COUNTER: + if (req_len !=3D sizeof(struct rpmb_frame) || resp_len !=3D sizeof(struc= t rpmb_frame)) + return -EINVAL; + need_result_read =3D false; + break; + case RPMB_WRITE_DATA: + if (req_len % sizeof(struct rpmb_frame) || resp_len !=3D sizeof(struct r= pmb_frame)) + return -EINVAL; + break; + case RPMB_READ_DATA: + if (req_len !=3D sizeof(struct rpmb_frame) || resp_len % sizeof(struct r= pmb_frame)) + return -EINVAL; + need_result_read =3D false; + break; + default: + dev_err(dev, "Unknown request type=3D0x%04x\n", req_type); + return -EINVAL; + } + + protocol_id =3D ufs_rpmb->region_id << 8 | UFS_RPMB_SEC_PROTOCOL_ID; + + ret =3D ufs_sec_submit(hba, protocol_id, req, req_len, true); + if (ret) { + dev_err(dev, "Command failed with ret=3D%d\n", ret); + return ret; + } + + if (need_result_read) { + struct rpmb_frame *frm_resp =3D (struct rpmb_frame *)resp; + + memset(frm_resp, 0, sizeof(*frm_resp)); + frm_resp->req_resp =3D cpu_to_be16(RPMB_RESULT_READ); + ret =3D ufs_sec_submit(hba, protocol_id, resp, resp_len, true); + if (ret) { + dev_err(dev, "Result read request failed with ret=3D%d\n", ret); + return ret; + } + } + + if (!ret) { + ret =3D ufs_sec_submit(hba, protocol_id, resp, resp_len, false); + if (ret) + dev_err(dev, "Response read failed with ret=3D%d\n", ret); + } + + return ret; +} + +static void ufs_rpmb_device_release(struct device *dev) +{ + struct ufs_rpmb_dev *ufs_rpmb =3D dev_get_drvdata(dev); + + rpmb_dev_unregister(ufs_rpmb->rdev); +} + +/* UFS RPMB device registration */ +int ufs_rpmb_probe(struct ufs_hba *hba) +{ + struct ufs_rpmb_dev *ufs_rpmb, *it, *tmp; + struct rpmb_dev *rdev; + char *cid =3D NULL; + int region; + u32 cap; + int ret; + + if (!hba->ufs_rpmb_wlun || hba->dev_info.b_advanced_rpmb_en) { + dev_info(hba->dev, "Skip OP-TEE RPMB registration\n"); + return -ENODEV; + } + + /* Check if device_id is available */ + if (!hba->dev_info.device_id) { + dev_err(hba->dev, "UFS Device ID not available\n"); + return -EINVAL; + } + + INIT_LIST_HEAD(&hba->rpmbs); + + struct rpmb_descr descr =3D { + .type =3D RPMB_TYPE_UFS, + .route_frames =3D ufs_rpmb_route_frames, + .reliable_wr_count =3D hba->dev_info.rpmb_io_size, + }; + + for (region =3D 0; region < ARRAY_SIZE(hba->dev_info.rpmb_region_size); r= egion++) { + cap =3D hba->dev_info.rpmb_region_size[region]; + if (!cap) + continue; + + ufs_rpmb =3D devm_kzalloc(hba->dev, sizeof(*ufs_rpmb), GFP_KERNEL); + if (!ufs_rpmb) { + ret =3D -ENOMEM; + goto err_out; + } + + ufs_rpmb->hba =3D hba; + ufs_rpmb->dev.parent =3D &hba->ufs_rpmb_wlun->sdev_gendev; + ufs_rpmb->dev.bus =3D &ufs_rpmb_bus_type; + ufs_rpmb->dev.release =3D ufs_rpmb_device_release; + dev_set_name(&ufs_rpmb->dev, "ufs_rpmb%d", region); + + /* Set driver data BEFORE device_register */ + dev_set_drvdata(&ufs_rpmb->dev, ufs_rpmb); + + ret =3D device_register(&ufs_rpmb->dev); + if (ret) { + dev_err(hba->dev, "Failed to register UFS RPMB device %d\n", region); + put_device(&ufs_rpmb->dev); + goto err_out; + } + + /* Create unique ID by appending region number to device_id */ + cid =3D kasprintf(GFP_KERNEL, "%s-R%d", hba->dev_info.device_id, region); + if (!cid) { + device_unregister(&ufs_rpmb->dev); + ret =3D -ENOMEM; + goto err_out; + } + + descr.dev_id =3D cid; + descr.dev_id_len =3D strlen(cid); + descr.capacity =3D cap; + + /* Register RPMB device */ + rdev =3D rpmb_dev_register(&ufs_rpmb->dev, &descr); + if (IS_ERR(rdev)) { + dev_err(hba->dev, "Failed to register UFS RPMB device.\n"); + device_unregister(&ufs_rpmb->dev); + ret =3D PTR_ERR(rdev); + goto err_out; + } + + kfree(cid); + cid =3D NULL; + + ufs_rpmb->rdev =3D rdev; + ufs_rpmb->region_id =3D region; + + list_add_tail(&ufs_rpmb->node, &hba->rpmbs); + + dev_info(hba->dev, "UFS RPMB region %d registered (capacity=3D%u)\n", re= gion, cap); + } + + return 0; +err_out: + kfree(cid); + list_for_each_entry_safe(it, tmp, &hba->rpmbs, node) { + list_del(&it->node); + device_unregister(&it->dev); + } + + return ret; +} + +/* UFS RPMB remove handler */ +void ufs_rpmb_remove(struct ufs_hba *hba) +{ + struct ufs_rpmb_dev *ufs_rpmb, *tmp; + + if (list_empty(&hba->rpmbs)) + return; + + /* Remove all registered RPMB devices */ + list_for_each_entry_safe(ufs_rpmb, tmp, &hba->rpmbs, node) { + dev_info(hba->dev, "Removing UFS RPMB region %d\n", ufs_rpmb->region_id); + /* Remove from list first */ + list_del(&ufs_rpmb->node); + /* Unregister device */ + device_unregister(&ufs_rpmb->dev); + } + + dev_info(hba->dev, "All UFS RPMB devices unregistered\n"); +} + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("OP-TEE UFS RPMB driver"); diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h index f3eeaf45cfdb..6020841f5a6d 100644 --- a/drivers/ufs/core/ufshcd-priv.h +++ b/drivers/ufs/core/ufshcd-priv.h @@ -419,4 +419,17 @@ static inline u32 ufshcd_mcq_get_sq_head_slot(struct u= fs_hw_queue *q) return val / sizeof(struct utp_transfer_req_desc); } =20 +#ifdef CONFIG_RPMB +int ufs_rpmb_probe(struct ufs_hba *hba); +void ufs_rpmb_remove(struct ufs_hba *hba); +#else +static inline int ufs_rpmb_probe(struct ufs_hba *hba) +{ + return 0; +} +static inline void ufs_rpmb_remove(struct ufs_hba *hba) +{ +} +#endif + #endif /* _UFSHCD_PRIV_H_ */ diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index a5849e0c6c35..904d89775a5f 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -5255,10 +5255,15 @@ static void ufshcd_lu_init(struct ufs_hba *hba, str= uct scsi_device *sdev) desc_buf[UNIT_DESC_PARAM_LU_WR_PROTECT] =3D=3D UFS_LU_POWER_ON_WP) hba->dev_info.is_lu_power_on_wp =3D true; =20 - /* In case of RPMB LU, check if advanced RPMB mode is enabled */ - if (desc_buf[UNIT_DESC_PARAM_UNIT_INDEX] =3D=3D UFS_UPIU_RPMB_WLUN && - desc_buf[RPMB_UNIT_DESC_PARAM_REGION_EN] & BIT(4)) - hba->dev_info.b_advanced_rpmb_en =3D true; + /* In case of RPMB LU, check if advanced RPMB mode is enabled, and get re= gion size */ + if (desc_buf[UNIT_DESC_PARAM_UNIT_INDEX] =3D=3D UFS_UPIU_RPMB_WLUN) { + if (desc_buf[RPMB_UNIT_DESC_PARAM_REGION_EN] & BIT(4)) + hba->dev_info.b_advanced_rpmb_en =3D true; + hba->dev_info.rpmb_region_size[0] =3D desc_buf[RPMB_UNIT_DESC_PARAM_REGI= ON0_SIZE]; + hba->dev_info.rpmb_region_size[1] =3D desc_buf[RPMB_UNIT_DESC_PARAM_REGI= ON1_SIZE]; + hba->dev_info.rpmb_region_size[2] =3D desc_buf[RPMB_UNIT_DESC_PARAM_REGI= ON2_SIZE]; + hba->dev_info.rpmb_region_size[3] =3D desc_buf[RPMB_UNIT_DESC_PARAM_REGI= ON3_SIZE]; + } =20 =20 kfree(desc_buf); @@ -8190,8 +8195,11 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba) ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_RPMB_WLUN), NULL); if (IS_ERR(sdev_rpmb)) { ret =3D PTR_ERR(sdev_rpmb); + hba->ufs_rpmb_wlun =3D NULL; + dev_err(hba->dev, "%s: RPMB WLUN not found\n", __func__); goto remove_ufs_device_wlun; } + hba->ufs_rpmb_wlun =3D sdev_rpmb; ufshcd_blk_pm_runtime_init(sdev_rpmb); scsi_device_put(sdev_rpmb); =20 @@ -8459,6 +8467,67 @@ static void ufs_init_rtc(struct ufs_hba *hba, u8 *de= sc_buf) dev_info->rtc_update_period =3D 0; } =20 +/** + * ufshcd_create_device_id - Generate unique device identifier string + * @hba: per-adapter instance + * @desc_buf: device descriptor buffer + * + * Creates a unique device ID string combining manufacturer ID, spec versi= on, + * model name, serial number (as hex), device version, and manufacture dat= e. + * + * Returns: Allocated device ID string on success, NULL on failure + */ +static char *ufshcd_create_device_id(struct ufs_hba *hba, u8 *desc_buf) +{ + struct ufs_dev_info *dev_info =3D &hba->dev_info; + u16 manufacture_date; + u16 device_version; + u8 *serial_number; + char *serial_hex; + char *device_id; + u8 serial_index; + int serial_len; + int ret; + + serial_index =3D desc_buf[DEVICE_DESC_PARAM_SN]; + + ret =3D ufshcd_read_string_desc(hba, serial_index, &serial_number, SD_RAW= ); + if (ret < 0) { + dev_err(hba->dev, "Failed reading Serial Number. err =3D %d\n", ret); + return NULL; + } + + device_version =3D get_unaligned_be16(&desc_buf[DEVICE_DESC_PARAM_DEV_VER= ]); + manufacture_date =3D get_unaligned_be16(&desc_buf[DEVICE_DESC_PARAM_MANF_= DATE]); + + serial_len =3D ret; + /* Allocate buffer for hex string: 2 chars per byte + null terminator */ + serial_hex =3D kzalloc(serial_len * 2 + 1, GFP_KERNEL); + if (!serial_hex) { + kfree(serial_number); + return NULL; + } + + bin2hex(serial_hex, serial_number, serial_len); + + /* + * Device ID format is ABI with secure world - do not change without firm= ware + * coordination. + */ + device_id =3D kasprintf(GFP_KERNEL, "%04X-%04X-%s-%s-%04X-%04X", + dev_info->wmanufacturerid, dev_info->wspecversion, + dev_info->model, serial_hex, device_version, + manufacture_date); + + kfree(serial_hex); + kfree(serial_number); + + if (!device_id) + dev_warn(hba->dev, "Failed to allocate unique device ID\n"); + + return device_id; +} + static int ufs_get_device_desc(struct ufs_hba *hba) { int err; @@ -8510,6 +8579,9 @@ static int ufs_get_device_desc(struct ufs_hba *hba) goto out; } =20 + /* Generate unique device ID */ + dev_info->device_id =3D ufshcd_create_device_id(hba, desc_buf); + hba->luns_avail =3D desc_buf[DEVICE_DESC_PARAM_NUM_LU] + desc_buf[DEVICE_DESC_PARAM_NUM_WLU]; =20 @@ -8545,6 +8617,8 @@ static void ufs_put_device_desc(struct ufs_hba *hba) =20 kfree(dev_info->model); dev_info->model =3D NULL; + kfree(dev_info->device_id); + dev_info->device_id =3D NULL; } =20 /** @@ -8688,6 +8762,8 @@ static int ufshcd_device_geo_params_init(struct ufs_h= ba *hba) else if (desc_buf[GEOMETRY_DESC_PARAM_MAX_NUM_LUN] =3D=3D 0) hba->dev_info.max_lu_supported =3D 8; =20 + hba->dev_info.rpmb_io_size =3D desc_buf[GEOMETRY_DESC_PARAM_RPMB_RW_SIZE]; + out: kfree(desc_buf); return err; @@ -8874,6 +8950,7 @@ static int ufshcd_add_lus(struct ufs_hba *hba) =20 ufs_bsg_probe(hba); scsi_scan_host(hba->host); + ufs_rpmb_probe(hba); =20 out: return ret; @@ -10428,6 +10505,7 @@ void ufshcd_remove(struct ufs_hba *hba) ufshcd_rpm_get_sync(hba); ufs_hwmon_remove(hba); ufs_bsg_remove(hba); + ufs_rpmb_remove(hba); ufs_sysfs_remove_nodes(hba->dev); cancel_delayed_work_sync(&hba->ufs_rtc_update_work); blk_mq_destroy_queue(hba->tmf_queue); diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h index 245a6a829ce9..ab8f6c07b5a2 100644 --- a/include/ufs/ufs.h +++ b/include/ufs/ufs.h @@ -651,6 +651,11 @@ struct ufs_dev_info { u8 rtt_cap; /* bDeviceRTTCap */ =20 bool hid_sup; + + /* Unique device ID string (manufacturer+model+serial+version+date) */ + char *device_id; + u8 rpmb_io_size; + u8 rpmb_region_size[4]; }; =20 #endif /* End of Header */ diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 4fb1998b84cf..35ad65e97e9d 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -826,6 +826,7 @@ enum ufshcd_mcq_opr { * @host: Scsi_Host instance of the driver * @dev: device handle * @ufs_device_wlun: WLUN that controls the entire UFS device. + * @ufs_rpmb_wlun: RPMB WLUN SCSI device * @hwmon_device: device instance registered with the hwmon core. * @curr_dev_pwr_mode: active UFS device power mode. * @uic_link_state: active state of the link to the UFS device. @@ -941,8 +942,8 @@ enum ufshcd_mcq_opr { * @pm_qos_mutex: synchronizes PM QoS request and status updates * @critical_health_count: count of critical health exceptions * @dev_lvl_exception_count: count of device level exceptions since last r= eset - * @dev_lvl_exception_id: vendor specific information about the - * device level exception event. + * @dev_lvl_exception_id: vendor specific information about the device lev= el exception event. + * @rpmbs: list of OP-TEE RPMB devices (one per RPMB region) */ struct ufs_hba { void __iomem *mmio_base; @@ -960,6 +961,7 @@ struct ufs_hba { struct Scsi_Host *host; struct device *dev; struct scsi_device *ufs_device_wlun; + struct scsi_device *ufs_rpmb_wlun; =20 #ifdef CONFIG_SCSI_UFS_HWMON struct device *hwmon_device; @@ -1119,6 +1121,8 @@ struct ufs_hba { u64 dev_lvl_exception_id; =20 u32 vcc_off_delay_us; + + struct list_head rpmbs; }; =20 /** --=20 2.34.1