From nobody Sat Sep 26 20:01:36 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1788923550; cv=none; d=zohomail.com; s=zohoarc; b=Azm109HSM8yKyrrWhqOWxwnY8SKyk7wL7oi75OEGNI+1v/19FpqFI87mc2O6GVwMHZ9CqMZf3cxHDhzXbAXBERKAcn/aJb6U0jeu+OUfAJbnGrPBRXr+zWUODc3xsmQvyHvkpmGTa0tn6LlFQfTuPSVW4LTKTBCBiZ/srRAWyrg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788923550; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=o1abFe5QNIdjftxiivQ5ppUFUH7EKLKLKn1t+ajtyG4=; b=kDtjUlWnTKgR7D9ENtFVFGCW6XhmnRGFQJMvmMAxBxu94JBIr/b46abVJgPZY7aMGt9KhdvI8r6qPk+vW5gonM9493I93Ts0HBFEXYSYapof++gw5rFoSRrEyi6iA2SyBFDvy68dH0N8UwmeSStgpMW4iN29OcU2bhBSTTKiynM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788923550170361.3627865443941; Tue, 8 Sep 2026 20:12:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x48jC-0002Y5-Tt; Tue, 08 Sep 2026 23:12:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <3ds6gagoKCvElmTgeXrcanZhhZeX.VhfjXfn-WXoXeghgZgn.hkZ@flex--stanleyjhu.bounces.google.com>) id 1x48j5-0002Wh-5Z for qemu-devel@nongnu.org; Tue, 08 Sep 2026 23:11:56 -0400 Received: from mail-pj1-x1046.google.com ([2607:f8b0:4864:20::1046]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3ds6gagoKCvElmTgeXrcanZhhZeX.VhfjXfn-WXoXeghgZgn.hkZ@flex--stanleyjhu.bounces.google.com>) id 1x48j3-0004zI-3F for qemu-devel@nongnu.org; Tue, 08 Sep 2026 23:11:54 -0400 Received: by mail-pj1-x1046.google.com with SMTP id 98e67ed59e1d1-3968bb86fb7so6526756a91.2 for ; Tue, 08 Sep 2026 20:11:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1788923511; x=1789528311; darn=nongnu.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=o1abFe5QNIdjftxiivQ5ppUFUH7EKLKLKn1t+ajtyG4=; b=gfjTAWiS4wcNrQhvHdLIbbf7s8j/N3y4VdbFaalZNVAbGYQLoG0iIkIDYDQ3So8QX3 wZvEKoUYr5O/gVU5n84HLmubG6A8yOGXUPm8W0jIa4RqlbE1KhVKJAGavJtSL9d91Kct N6iScK4hCK6uBeyf4plTTArzBm7TXa6lqrDQjo/GVuZf2E5vL8TverE6W7LMYYBYhmIS BoJQPhzmsQYNuolb1QHJZgFtuwRFvDU0o3G8oOOBfi2LsW86Pez4Znaib1inUM9Sit/J sNtcU4GCtanRKav7pTrq2pEqB8xPLr9ZVZvp0VfrvUuFGHWuDVnXmLrw/B11/lWi98rf 1w+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788923511; x=1789528311; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=o1abFe5QNIdjftxiivQ5ppUFUH7EKLKLKn1t+ajtyG4=; b=X96vXu4uzV68Nd4hHoNBWRTIJrax83l7gAup9W7uLAnKgTnCQqY9KU3GI1WiV3HgTd SYvSmvBNM9v8pbYMhG4T1VYAFokFLZzO8H6OOQtRtC6iE+E58MDTQAn+L/px6P5+iXsH Lc/NWN7TovRh79Fa864n0D9mrXWOMmoLEfL5ru6ve/Gg/cYpuWmmxpGdSzDb++KyAk9D Vwj3aqcs2uQu9hyYJZp5/6XnyyFaKgfNHk8iIbTPkoF2sFKSsYo0Di4EhNxG8PA05pG+ ac/aR7cv2Yy2WmZpwHiSPw4s1cyD8mTkBoJ4CFZrG7kNXeIvMN2za4zctc2AqA5O6Jz5 W2gg== X-Forwarded-Encrypted: i=1; AKwUvBzT2esRH8btZryKMwcxH6Pz26wcF+XrjNwRr0ru0li2I2ECBdywpTtxnbCx8799oSYy/k/RsCEHfm4S@nongnu.org X-Gm-Message-State: AFuF++m04/34chBU3/IXhlh65yEsWVySy5QswEYOQH+SPlrmfamooxOO HalDYShjuLmhWOgXoEfP0ZP8rIYq95GbKn3lu6aiPaPo9iqoXszJRjLJbXi4iSc64VOvS8xzC8T onpkt1E2x2312LmAeGAvcSg== X-Received: from pjni21.prod.google.com ([2002:a17:90a:8395:b0:39b:9879:9a]) (user=stanleyjhu job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:4e8f:b0:38e:5c6:4db9 with SMTP id 98e67ed59e1d1-39b261ba63bmr49416131a91.11.1788923510934; Tue, 08 Sep 2026 20:11:50 -0700 (PDT) Date: Wed, 9 Sep 2026 11:11:44 +0800 In-Reply-To: <20260909031146.1646684-1-stanleyjhu@google.com> Mime-Version: 1.0 References: <20260909031146.1646684-1-stanleyjhu@google.com> X-Mailer: git-send-email 2.55.0.1007.g17ff1f9808-goog Message-ID: <20260909031146.1646684-2-stanleyjhu@google.com> Subject: [PATCH v2 1/3] hw/ufs: Track SCSIRequest and cancel pending requests in ufs_clear_req From: Stanley Jhu To: Jeuk Kim , qemu-devel@nongnu.org Cc: Brian Kao , Stanley Jhu Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1046; envelope-from=3ds6gagoKCvElmTgeXrcanZhhZeX.VhfjXfn-WXoXeghgZgn.hkZ@flex--stanleyjhu.bounces.google.com; helo=mail-pj1-x1046.google.com X-Spam_score_int: -95 X-Spam_score: -9.6 X-Spam_bar: --------- X-Spam_report: (-9.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @google.com) X-ZM-MESSAGEID: 1788923553725158500 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In the UFS emulator, outstanding SCSI requests are dispatched asynchronously to the block layer via scsi_req_enqueue(). When requests are cleared or aborted (e.g. during HCE reset or TMR aborts), ufs_clear_req() releases the scatter-gather list without cancelling the pending SCSIRequest. If an asynchronous AIO callback completes afterwards, ufs_scsi_command_complete() dereferences stale or freed request state, resulting in use-after-free hazards. Track the active SCSIRequest in UfsRequest and explicitly cancel any in-fli= ght requests in ufs_clear_req() before freeing request resources. To prevent dangling references during cancellation cascades, decouple and clear req->s= req in completion and cancellation handlers. Signed-off-by: Stanley Jhu --- hw/ufs/lu.c | 12 ++++++++++++ hw/ufs/ufs.c | 6 ++++++ hw/ufs/ufs.h | 1 + 3 files changed, 19 insertions(+) diff --git a/hw/ufs/lu.c b/hw/ufs/lu.c index bdb1650851..a62ebb51fd 100644 --- a/hw/ufs/lu.c +++ b/hw/ufs/lu.c @@ -173,6 +173,12 @@ static void ufs_scsi_command_complete(SCSIRequest *scs= i_req, size_t resid) int16_t status =3D scsi_req->status; uint32_t transfered_len =3D scsi_req->cmd.xfer - resid; =20 + if (!req) { + return; + } + + req->sreq =3D NULL; + /* WB / HID accounting should only happen for successful commands */ if (status =3D=3D GOOD) { ufs_wb_process_write_req(req, transfered_len); @@ -190,6 +196,11 @@ static void ufs_scsi_command_complete(SCSIRequest *scs= i_req, size_t resid) =20 static void ufs_scsi_command_cancelled(SCSIRequest *scsi_req) { + UfsRequest *req =3D scsi_req->hba_private; + + if (req) { + req->sreq =3D NULL; + } scsi_req->hba_private =3D NULL; scsi_req_unref(scsi_req); } @@ -389,6 +400,7 @@ static UfsReqResult ufs_process_scsi_cmd(UfsLu *lu, Ufs= Request *req) SCSIRequest *scsi_req =3D scsi_req_new(lu->scsi_dev, task_tag, lu->lun, req->req_upiu.sc.cdb, UFS_CDB_SIZE, req); + req->sreq =3D scsi_req; =20 uint32_t len =3D scsi_req_enqueue(scsi_req); if (len) { diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c index 3c4d7424da..adae6639e1 100644 --- a/hw/ufs/ufs.c +++ b/hw/ufs/ufs.c @@ -2221,6 +2221,12 @@ void ufs_complete_req(UfsRequest *req, UfsReqResult = req_result) =20 static void ufs_clear_req(UfsRequest *req) { + if (req->sreq !=3D NULL) { + SCSIRequest *sreq =3D req->sreq; + req->sreq =3D NULL; + scsi_req_cancel(sreq); + } + if (req->sg !=3D NULL) { qemu_sglist_destroy(req->sg); g_free(req->sg); diff --git a/hw/ufs/ufs.h b/hw/ufs/ufs.h index 6f2693b7ca..265a43faaa 100644 --- a/hw/ufs/ufs.h +++ b/hw/ufs/ufs.h @@ -60,6 +60,7 @@ typedef struct UfsRequest { UtpUpiuRsp rsp_upiu; =20 /* for scsi command */ + SCSIRequest *sreq; QEMUSGList *sg; uint32_t data_len; =20 --=20 2.55.0.1007.g17ff1f9808-goog From nobody Sat Sep 26 20:01:36 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1788923550; cv=none; d=zohomail.com; s=zohoarc; b=bV8OnGUdu+HJSq5hF+poeyaLQ5ZpRfbyBlzEEeccDum3RRtHj8I5bVbGRPdHQPGK2knQWU2WiKLfc8qGiBjY+GWZ3BoZ9XBBzML3eZr5pGm0orEzJZR5kJv/iZV4Y5/LwIughxxnGw3YBiHLzPFHRu520xikNfzqlPPu5owzV6U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788923550; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Uvk5Eyi7WBTx5w4jU3FUojn97We0KNofjEPwHLpdBsg=; b=CnN7K7ChOpeM4OGWuHgYnm6XPydOl5vbVvUj0w1kTVWPIMSOlnCG0c2I/YmGATm9/9bDnygu9Uz1vwIlqxb1Jl2GeMWL03WUEGumcNN8BZ5+acGa8XfpqnaU+lZvfATfaImrma4AWXnL35YxIQSy4gHPIAX+DCred+5lZDy87zA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788923550347598.6815596853345; Tue, 8 Sep 2026 20:12:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x48jC-0002Xz-Qu; Tue, 08 Sep 2026 23:12:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <3eM6gagoKCvMnoVigZtecpbjjbgZ.XjhlZhp-YZqZgijibip.jmb@flex--stanleyjhu.bounces.google.com>) id 1x48j7-0002X7-6i for qemu-devel@nongnu.org; Tue, 08 Sep 2026 23:11:58 -0400 Received: from mail-pj1-x1047.google.com ([2607:f8b0:4864:20::1047]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3eM6gagoKCvMnoVigZtecpbjjbgZ.XjhlZhp-YZqZgijibip.jmb@flex--stanleyjhu.bounces.google.com>) id 1x48j5-0004zV-8Q for qemu-devel@nongnu.org; Tue, 08 Sep 2026 23:11:56 -0400 Received: by mail-pj1-x1047.google.com with SMTP id 98e67ed59e1d1-39b6416441eso5400413a91.1 for ; Tue, 08 Sep 2026 20:11:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1788923513; x=1789528313; darn=nongnu.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=Uvk5Eyi7WBTx5w4jU3FUojn97We0KNofjEPwHLpdBsg=; b=cN95mySY8QRo4xfCU3vnXjnuJh6wS7N4dduzHqc+JSn897NBdkwLNmt74o9lK/3Z0c rehdeRh36nLiIDZ+DmHcLO0xvETXaDGyR/5DbOigu0557QDI9HeZiAqH2idxDKg0aQKF Nh6B68GWEakTzHw2SDMxqOuMlxPwbCoxonj7Xd4AqRv16Hsdb0fUFQsCkUwuppzyBu/j G/lTf1+Gq0wLU6gpEY5UossY2jNVrN3Yl6ed/bXpvRsM7z1o3Fz/kT1V3v84h+J1rcr9 E8w/JxEz/0Sx+LydYSwnYVQKkbjbmheqa1Wnz6ZIPCU0/zeS686BWW/A08BNAmta1Rng xYog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788923513; x=1789528313; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Uvk5Eyi7WBTx5w4jU3FUojn97We0KNofjEPwHLpdBsg=; b=Q0y/DR3h4YIHchhE6FLeFeyalrgUHVs76d2CcoQP0u+eVbtf4YeckR+p4aGknQOoPs T0Uo/ytIM1Xag/MSEgGJ7OngyafTrVuWpx+O744R1kkq6mMFcLriKwvsBt7tFVwwneZO X8FoOD58a0Md99tlAMOlsqADmZ2Ygpi+Dv1F5FSfv6kymp4xd4anwDQdGhFA/WV/aZuC t4lO21tbpGK5AQ69lDu9L//pU4+j8HO+ZOWoWCNEktJG37ni5/5pnYR5GeMo550rvrJ7 LDo+a7BIGqZzMZa9TWAn/e2nOvwelJ649HsD5hLOkWd5inl82C3odIKjIgKpTkEZZru2 Yk1g== X-Forwarded-Encrypted: i=1; AKwUvBxb0E5gkAJvxkvZUFOy2RYI2JFTFB4a/T6zuiyEMB6XhgoeAmV359YHqM4x6ifsrIyI3IX/oWGlLRm3@nongnu.org X-Gm-Message-State: AFuF++lsAtSfvaPGKPv7FVx4WDRpUaE2vt29k1UvMCNK63QwP41bZjQA kySnIgLozU647lq1L7ZFAau7HCbcexTQTXDNgbrnFDnBvEdJZzngAx7t9g1EzPOTWtZ1O+HewQO ggCUrSwSl/v5cFcqoqxcAkA== X-Received: from pjye9.prod.google.com ([2002:a17:90a:ee09:b0:380:60d8:dafc]) (user=stanleyjhu job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90a:164f:b0:39b:3510:49e7 with SMTP id 98e67ed59e1d1-39b35105b52mr27154735a91.0.1788923512887; Tue, 08 Sep 2026 20:11:52 -0700 (PDT) Date: Wed, 9 Sep 2026 11:11:45 +0800 In-Reply-To: <20260909031146.1646684-1-stanleyjhu@google.com> Mime-Version: 1.0 References: <20260909031146.1646684-1-stanleyjhu@google.com> X-Mailer: git-send-email 2.55.0.1007.g17ff1f9808-goog Message-ID: <20260909031146.1646684-3-stanleyjhu@google.com> Subject: [PATCH v2 2/3] hw/ufs: Support MCQ runtime interrupt and queue status registers From: Stanley Jhu To: Jeuk Kim , qemu-devel@nongnu.org Cc: Brian Kao , Stanley Jhu Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1047; envelope-from=3eM6gagoKCvMnoVigZtecpbjjbgZ.XjhlZhp-YZqZgijibip.jmb@flex--stanleyjhu.bounces.google.com; helo=mail-pj1-x1047.google.com X-Spam_score_int: -95 X-Spam_score: -9.6 X-Spam_bar: --------- X-Spam_report: (-9.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @google.com) X-ZM-MESSAGEID: 1788923553777158500 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" According to JEDEC UFSHCI 5.2.1 and 5.6, Multi-Circular Queue (MCQ) architecture provides per-queue runtime control and interrupt registers. When Linux initializes MCQ via ufshcd_mcq_make_queues_operational(), it configures operational registers (SQnRTC, SQnCTI, SQnIS/IE, CQnIS/IE, CQnIACR). Currently, QEMU treats these offsets as unhandled, generating "invalid register offset" warnings and failing queue lifecycle transitions. Implement MCQ runtime operational register handling: - Support SQ run-time control (SQnRTC) to start, stop, and clean up submiss= ion queues, updating run-time status (SQnRTS) and synchronizing with the SQ processing bottom half. - Support per-queue interrupt status and enable registers (SQnIS/IE, CQnIS/= IE). Implement write-1-to-clear semantics and dynamically synchronize the glob= al CQES (CQ Event Status) bit in IS to prevent interrupt storms. - Store queue configuration for interrupt aggregation (CQnIACR) and complet= ion timeout intervals (SQnCTI). - Enforce controller reset state machine rules: guard MMIO reads when HCE= =3D0, and reinitialize operational registers across HCE resets while preserving MCQ capability configurations. Signed-off-by: Stanley Jhu --- hw/ufs/trace-events | 1 + hw/ufs/ufs.c | 73 +++++++++++++++++++++++++++++++++++++++++++-- include/block/ufs.h | 9 ++++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/hw/ufs/trace-events b/hw/ufs/trace-events index 922293355b..d8173b12b6 100644 --- a/hw/ufs/trace-events +++ b/hw/ufs/trace-events @@ -14,6 +14,7 @@ ufs_process_uiccmd(uint32_t uiccmd, uint32_t ucmdarg1, ui= nt32_t ucmdarg2, uint32 ufs_mcq_complete_req(uint8_t qid) "sqid %"PRIu8"" ufs_mcq_create_sq(uint8_t sqid, uint8_t cqid, uint64_t addr, uint16_t size= ) "mcq create sq sqid %"PRIu8", cqid %"PRIu8", addr 0x%"PRIx64", size %"PRI= u16"" ufs_mcq_create_cq(uint8_t cqid, uint64_t addr, uint16_t size) "mcq create = cq cqid %"PRIu8", addr 0x%"PRIx64", size %"PRIu16"" +ufs_write_mcq_op_reg(uint8_t qid, uint32_t offset, uint32_t data) "qid %"P= RIu8", offset 0x%"PRIx32", data 0x%"PRIx32"" ufs_hce_reset(void) "HCE 1 -> 0 reset: cancelling BHs, resetting MCQ and r= equest lists" =20 # error condition diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c index adae6639e1..4e22c31f89 100644 --- a/hw/ufs/ufs.c +++ b/hw/ufs/ufs.c @@ -446,13 +446,14 @@ static void ufs_mcq_process_sq(void *opaque) { UfsSq *sq =3D opaque; UfsHc *u =3D sq->u; + UfsMcqOpReg *opr =3D &u->mcq_op_reg[sq->sqid]; UfsSqEntry sqe; UfsRequest *req; hwaddr addr; uint16_t head =3D ufs_mcq_sq_head(u, sq->sqid); int err; =20 - if (u->resetting) { + if (u->resetting || FIELD_EX32(opr->sq.rts, SQRTS, STS)) { return; } =20 @@ -770,7 +771,17 @@ static void ufs_hce_reset(UfsHc *u) u->reg.utmrldbr =3D 0; u->reg.utrlcnr =3D 0; u->reg.utrlrsr =3D 0; + u->reg.utriacr =3D 0; + u->reg.utrlclr =3D 0; + if (u->params.mcq) { + u->reg.mcqconfig =3D FIELD_DP32(0, MCQCONFIG, MAC, 0x1f); + } else { + u->reg.mcqconfig =3D 0; + } + u->reg.ie =3D 0; u->reg.is =3D 0; + u->reg.utrlba =3D 0; + u->reg.utrlbau =3D 0; =20 /* 4. Free MCQ Queues and reset MCQ dynamic registers */ if (u->params.mcq) { @@ -983,6 +994,9 @@ static void ufs_write_mcq_op_reg(UfsHc *u, hwaddr offse= t, uint32_t data, =20 opr =3D &u->mcq_op_reg[qid]; =20 + trace_ufs_write_mcq_op_reg(qid, (uint32_t)(offset % sizeof(UfsMcqOpReg= )), + data); + switch (offset % sizeof(UfsMcqOpReg)) { case offsetof(UfsMcqOpReg, sq.tp): if (opr->sq.tp !=3D data) { @@ -990,6 +1004,38 @@ static void ufs_write_mcq_op_reg(UfsHc *u, hwaddr off= set, uint32_t data, } opr->sq.tp =3D data; break; + case offsetof(UfsMcqOpReg, sq.rtc): + opr->sq.rtc =3D data; + if (FIELD_EX32(data, SQRTC, ICU)) { + /* SQ_ICU: Initiate Cleanup (SQ_CUS =3D 1, RTC =3D 0) */ + opr->sq.rts =3D FIELD_DP32(opr->sq.rts, SQRTS, CUS, 1); + opr->sq.rts =3D FIELD_DP32(opr->sq.rts, SQRTS, RTC, 0); + } + if (FIELD_EX32(data, SQRTC, STOP)) { + /* SQ_STOP: Stop queue */ + opr->sq.rts =3D FIELD_DP32(opr->sq.rts, SQRTS, STS, 1); + if (u->sq[qid] && u->sq[qid]->bh) { + qemu_bh_cancel(u->sq[qid]->bh); + } + } else { + /* SQ_START: Start queue */ + opr->sq.rts =3D FIELD_DP32(opr->sq.rts, SQRTS, STS, 0); + opr->sq.rts =3D FIELD_DP32(opr->sq.rts, SQRTS, CUS, 0); + if (u->sq[qid] && u->sq[qid]->bh) { + qemu_bh_schedule(u->sq[qid]->bh); + } + } + break; + case offsetof(UfsMcqOpReg, sq.cti): + opr->sq.cti =3D data; + break; + case offsetof(UfsMcqOpReg, sq_int.is): + opr->sq_int.is &=3D ~data; + ufs_irq_check(u); + break; + case offsetof(UfsMcqOpReg, sq_int.ie): + opr->sq_int.ie =3D data; + break; case offsetof(UfsMcqOpReg, cq.hp): { UfsCq *cq =3D u->cq[qid]; =20 @@ -1006,8 +1052,27 @@ static void ufs_write_mcq_op_reg(UfsHc *u, hwaddr of= fset, uint32_t data, ufs_mcq_update_cq_head(u, qid, data); break; } - case offsetof(UfsMcqOpReg, cq_int.is): + case offsetof(UfsMcqOpReg, cq_int.is): { + bool pending =3D false; + opr->cq_int.is &=3D ~data; + for (int i =3D 0; i < ARRAY_SIZE(u->mcq_op_reg); i++) { + if (u->mcq_op_reg[i].cq_int.is) { + pending =3D true; + break; + } + } + if (!pending) { + u->reg.is =3D FIELD_DP32(u->reg.is, IS, CQES, 0); + } + ufs_irq_check(u); + break; + } + case offsetof(UfsMcqOpReg, cq_int.ie): + opr->cq_int.ie =3D data; + break; + case offsetof(UfsMcqOpReg, cq_int.iacr): + opr->cq_int.iacr =3D data; break; default: trace_ufs_err_invalid_register_offset(offset); @@ -1029,6 +1094,10 @@ static uint64_t ufs_mmio_read(void *opaque, hwaddr a= ddr, unsigned size) offset =3D addr - ufs_mcq_reg_addr(u, 0); ptr =3D (uint32_t *)&u->mcq_reg; } else if (ufs_is_mcq_op_reg(u, addr, size)) { + if (!FIELD_EX32(u->reg.hce, HCE, HCE)) { + trace_ufs_err_invalid_register_offset(addr); + return 0xffffffff; + } offset =3D addr - ufs_mcq_op_reg_addr(u, 0); ptr =3D (uint32_t *)&u->mcq_op_reg; } else { diff --git a/include/block/ufs.h b/include/block/ufs.h index d19b3c65ef..00591aa755 100644 --- a/include/block/ufs.h +++ b/include/block/ufs.h @@ -224,6 +224,15 @@ typedef struct QEMU_PACKED UfsMcqSqReg { uint32_t rts; } UfsMcqSqReg; =20 +REG32(SQRTC, offsetof(UfsMcqSqReg, rtc)) + FIELD(SQRTC, STOP, 0, 1) + FIELD(SQRTC, ICU, 1, 1) + +REG32(SQRTS, offsetof(UfsMcqSqReg, rts)) + FIELD(SQRTS, STS, 0, 1) + FIELD(SQRTS, CUS, 1, 1) + FIELD(SQRTS, RTC, 4, 4) + typedef struct QEMU_PACKED UfsMcqCqReg { uint32_t hp; uint32_t tp; --=20 2.55.0.1007.g17ff1f9808-goog From nobody Sat Sep 26 20:01:36 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1788923550; cv=none; d=zohomail.com; s=zohoarc; b=blhxabcQ4fA3B9Ef3jgxllQ5b33MGAYZRmzpiMWiHA534HFGXKVhiTKHyGevYiU8QNyhd8c9kWwTBhjxxoW+iadLFfzuqeu/2vTykpV5eZG3T4qPYULybkhIPvwKqg7rA0KyqRvBYxnCpKm3INOTNEtBhGSkSYSEGAnDzJ61RFg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788923550; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=QvjQ3EEZOav8WbIfKiSEOaKv4sRoYmiBFLRu7TD6Ts4=; b=m1OGeRx3i8isTOD1UPngNxQBnAlZWrTCYl1ACR9c26UoKroodwvfri1++24UnLN6bUH8EYirPCuybO6gL2L46GnZKZuVd/lBsLjOfWa2G0jp2DRZKq5krvXOgCgdZmQiQStEyT6gzJSagQKE1Ppu+bHmUXLkrvhJWEF3RPxuKKc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1788923550843761.0854102421526; Tue, 8 Sep 2026 20:12:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1x48jE-0002Yo-V0; Tue, 08 Sep 2026 23:12:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <3es6gagoKCvUpqXkibvgerdlldib.Zljnbjr-absbiklkdkr.lod@flex--stanleyjhu.bounces.google.com>) id 1x48jC-0002Y4-Kc for qemu-devel@nongnu.org; Tue, 08 Sep 2026 23:12:02 -0400 Received: from mail-pg1-x545.google.com ([2607:f8b0:4864:20::545]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3es6gagoKCvUpqXkibvgerdlldib.Zljnbjr-absbiklkdkr.lod@flex--stanleyjhu.bounces.google.com>) id 1x48j8-0004zv-K3 for qemu-devel@nongnu.org; Tue, 08 Sep 2026 23:12:00 -0400 Received: by mail-pg1-x545.google.com with SMTP id 41be03b00d2f7-cbedbd182f5so4334245a12.1 for ; Tue, 08 Sep 2026 20:11:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1788923515; x=1789528315; darn=nongnu.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=QvjQ3EEZOav8WbIfKiSEOaKv4sRoYmiBFLRu7TD6Ts4=; b=sMWe6x9ooshcN4PscCTr35tKuhLYAfUdnktit/tGjtpcQVkwzVXCLD2ajEUO3VLARn vQ96M7Dgl49tgsy8/FFZ5pFGMbLYj0wS6rDBeTS9URePt2fwPe6O6zpBypbilYVzmWyz YkC4ZD0QUps8OLr09lIqMaSjP/CEWv4LnvT4b3TpYwz8Hek/H8O/br8tNY/g7FYkjiAH e9FHPkKm5k1KbSjFbFkm3mKwQu6mFnf7SXhVt9vhu7Q3kB9xRUs7196QZVle5mfDBf3w eJrHMeTVVQh9b8RKu83PTysJL53/72OIrfBcalj7CwQSRJJYs/kzJy6/SNYJ8NPIXPIJ zw7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788923515; x=1789528315; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=QvjQ3EEZOav8WbIfKiSEOaKv4sRoYmiBFLRu7TD6Ts4=; b=YSY6zGnc01Rt/ybcD/4DpLSoxm7Wx4/z90FkFNQCW7LIn6PzJrGu4h+v/TPkuVSwu8 0q2pxtuqdUGsMuBRxHm+vqvCFAWBDCUxh4nI/kjWcszKV7CBMeB9+q7llV8LxsVmNNFc IOgPj1Eim6Qb3pHj2ya6lUeGn7x1/P6tIbb1Gyxx98Wj24TkPksAIO2/TscnYR/HQat1 3yP1Z4jfHKgKYeK8CC3DD0AezXWxVOFXas/9cmCV+J5n7PAiDTcIzngyfVDP9BSJoyq5 sYM3rCO1liPWxupsyt7snaDMI+odaGj/udu9eOgjES3HO6ATo5FsO5K+dL6RftnBaOrG PAWw== X-Forwarded-Encrypted: i=1; AKwUvBxgL6vIcuTN+vzcDoRW/LeUhxGGO7iBeMII1SUWIdxxK2z7GvTxIGKtEl9tSuLkcvcQ8YTP/HauiYyQ@nongnu.org X-Gm-Message-State: AFuF++k9RYwnO0uFl/qTlEsaOr2T7bHxXeSeGBJsSkjq6Wpn4KlQyYZw uyPk5TXy1uHG95HJ7b3HoQ5hy5biIV4Foczg2lM7975iHAR5i7UwNV+Xo+qBk4H5sfX8N2SUt7p 8gSBpYgCUfOnzjlimXbbJAw== X-Received: from pfrb15.prod.google.com ([2002:aa7:8ecf:0:b0:867:8d4a:901d]) (user=stanleyjhu job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:16:b0:3c4:3672:b86 with SMTP id adf61e73a8af0-3da9d69b429mr11065162637.3.1788923514779; Tue, 08 Sep 2026 20:11:54 -0700 (PDT) Date: Wed, 9 Sep 2026 11:11:46 +0800 In-Reply-To: <20260909031146.1646684-1-stanleyjhu@google.com> Mime-Version: 1.0 References: <20260909031146.1646684-1-stanleyjhu@google.com> X-Mailer: git-send-email 2.55.0.1007.g17ff1f9808-goog Message-ID: <20260909031146.1646684-4-stanleyjhu@google.com> Subject: [PATCH v2 3/3] hw/ufs: Implement Task Management Request (TMR) handling From: Stanley Jhu To: Jeuk Kim , qemu-devel@nongnu.org Cc: Brian Kao , Stanley Jhu Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::545; envelope-from=3es6gagoKCvUpqXkibvgerdlldib.Zljnbjr-absbiklkdkr.lod@flex--stanleyjhu.bounces.google.com; helo=mail-pg1-x545.google.com X-Spam_score_int: -95 X-Spam_score: -9.6 X-Spam_bar: --------- X-Spam_report: (-9.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @google.com) X-ZM-MESSAGEID: 1788923553766158500 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" According to JEDEC UFSHCI 5.2.1 (Section 7.3 "UTP Task Management"), the host controller processes Task Management Requests via the UTP Task Management Request List (UTMRL). When software triggers UTMRLDBR, the controller processes descriptors, executes the requested task management function (such as UFS_ABORT_TASK or UFS_QUERY_TASK), returns the response UPIU, and signals completion via the UTMRCS interrupt. Currently, QEMU does not implement the UTMRL doorbell or operational registers. Consequently, when Linux SCSI error recovery initiates task aborts via ufshcd_abort() or ufshcd_mcq_abort(), the requests time out and unnecessarily escalate to full host controller resets. Implement Task Management Request processing: - Support UTMRL registers (UTMRLDBR, UTMRLCLR, UTMRLRSR) and latch doorbell events per Section 5.3.3. - Handle UFS_ABORT_TASK and UFS_QUERY_TASK functions across both legacy UTRL and MCQ queues, locating outstanding requests by task tag. - Return compliant response UPIUs with appropriate status codes (setting bo= th response header and output parameters for Linux driver compatibility), and update descriptor OCS while preserving vendor/reserved fields. - Reset UTMRL operational registers on HCE reset. Signed-off-by: Stanley Jhu --- hw/ufs/trace-events | 1 + hw/ufs/ufs.c | 117 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 117 insertions(+), 1 deletion(-) diff --git a/hw/ufs/trace-events b/hw/ufs/trace-events index d8173b12b6..5e5a54a3fb 100644 --- a/hw/ufs/trace-events +++ b/hw/ufs/trace-events @@ -15,6 +15,7 @@ ufs_mcq_complete_req(uint8_t qid) "sqid %"PRIu8"" ufs_mcq_create_sq(uint8_t sqid, uint8_t cqid, uint64_t addr, uint16_t size= ) "mcq create sq sqid %"PRIu8", cqid %"PRIu8", addr 0x%"PRIx64", size %"PRI= u16"" ufs_mcq_create_cq(uint8_t cqid, uint64_t addr, uint16_t size) "mcq create = cq cqid %"PRIu8", addr 0x%"PRIx64", size %"PRIu16"" ufs_write_mcq_op_reg(uint8_t qid, uint32_t offset, uint32_t data) "qid %"P= RIu8", offset 0x%"PRIx32", data 0x%"PRIx32"" +ufs_process_tmr(uint8_t func, uint32_t tag, uint8_t resp) "query_func 0x%"= PRIx8", task_tag %"PRIu32", tm_resp 0x%"PRIx8"" ufs_hce_reset(void) "HCE 1 -> 0 reset: cancelling BHs, resetting MCQ and r= equest lists" =20 # error condition diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c index 4e22c31f89..ca5f6f2e96 100644 --- a/hw/ufs/ufs.c +++ b/hw/ufs/ufs.c @@ -771,8 +771,10 @@ static void ufs_hce_reset(UfsHc *u) u->reg.utmrldbr =3D 0; u->reg.utrlcnr =3D 0; u->reg.utrlrsr =3D 0; + u->reg.utmrlrsr =3D 0; u->reg.utriacr =3D 0; u->reg.utrlclr =3D 0; + u->reg.utmrlclr =3D 0; if (u->params.mcq) { u->reg.mcqconfig =3D FIELD_DP32(0, MCQCONFIG, MAC, 0x1f); } else { @@ -782,6 +784,8 @@ static void ufs_hce_reset(UfsHc *u) u->reg.is =3D 0; u->reg.utrlba =3D 0; u->reg.utrlbau =3D 0; + u->reg.utmrlba =3D 0; + u->reg.utmrlbau =3D 0; =20 /* 4. Free MCQ Queues and reset MCQ dynamic registers */ if (u->params.mcq) { @@ -818,6 +822,111 @@ static void ufs_hce_reset(UfsHc *u) ufs_irq_check(u); } =20 +static UfsRequest *ufs_find_req_by_tag(UfsHc *u, uint32_t task_tag) +{ + if (task_tag < u->params.nutrs) { + UfsRequest *req =3D &u->req_list[task_tag]; + if (req->state =3D=3D UFS_REQUEST_RUNNING || + req->state =3D=3D UFS_REQUEST_READY) { + return req; + } + } + + if (u->params.mcq) { + for (int q =3D 0; q < ARRAY_SIZE(u->sq); q++) { + UfsSq *sq =3D u->sq[q]; + if (!sq) { + continue; + } + for (int i =3D 0; i < sq->size; i++) { + UfsRequest *req =3D &sq->req[i]; + if (req->state =3D=3D UFS_REQUEST_RUNNING && + req->req_upiu.header.task_tag =3D=3D task_tag) { + return req; + } + } + } + } + + return NULL; +} + +static void ufs_process_tmr(UfsHc *u, uint32_t val) +{ + hwaddr base_addr =3D (((hwaddr)u->reg.utmrlbau) << 32) + u->reg.utmrlb= a; + uint32_t completed_mask =3D 0; + + u->reg.utmrldbr |=3D val; + + for (int i =3D 0; i < u->params.nutmrs; i++) { + if (val & (1 << i)) { + uint64_t desc_addr =3D base_addr + i * sizeof(UtpTaskReqDesc); + UtpTaskReqDesc desc; + uint8_t tm_func, tm_resp; + uint32_t task_tag; + + if (ufs_addr_read(u, desc_addr, &desc, sizeof(desc))) { + continue; + } + + tm_func =3D desc.upiu_req.req_header.query_func; + task_tag =3D be32_to_cpu(desc.upiu_req.input_param2); + + if (tm_func =3D=3D UFS_QUERY_TASK) { + UfsRequest *req =3D ufs_find_req_by_tag(u, task_tag); + + if (req) { + tm_resp =3D UFS_UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED; + } else { + tm_resp =3D UFS_UPIU_TASK_MANAGEMENT_FUNC_COMPL; + } + } else if (tm_func =3D=3D UFS_ABORT_TASK) { + UfsRequest *req =3D ufs_find_req_by_tag(u, task_tag); + + if (req) { + ufs_clear_req(req); + req->state =3D UFS_REQUEST_IDLE; + if (ufs_mcq_req(req)) { + QTAILQ_INSERT_TAIL(&req->sq->req_list, req, entry); + qemu_bh_schedule(req->sq->bh); + } else { + u->reg.utrldbr &=3D ~(1 << req->slot); + } + } + tm_resp =3D UFS_UPIU_TASK_MANAGEMENT_FUNC_COMPL; + } else { + tm_resp =3D UFS_UPIU_TASK_MANAGEMENT_FUNC_NOT_SUPPORTED; + } + + memset(&desc.upiu_rsp, 0, sizeof(desc.upiu_rsp)); + desc.header.dword_2 =3D cpu_to_le32( + (le32_to_cpu(desc.header.dword_2) & ~UFS_MASK_OCS) | + UFS_OCS_SUCCESS); + desc.upiu_rsp.rsp_header.trans_type =3D + UFS_UPIU_TRANSACTION_TASK_RSP; + desc.upiu_rsp.rsp_header.flags =3D 0; + desc.upiu_rsp.rsp_header.lun =3D desc.upiu_req.req_header.lun; + desc.upiu_rsp.rsp_header.task_tag =3D + desc.upiu_req.req_header.task_tag; + desc.upiu_rsp.rsp_header.response =3D tm_resp; + desc.upiu_rsp.output_param1 =3D cpu_to_be32(tm_resp); + + if (ufs_addr_write(u, desc_addr, &desc, sizeof(desc))) { + continue; + } + + trace_ufs_process_tmr(tm_func, task_tag, tm_resp); + u->reg.utmrldbr &=3D ~(1 << i); + completed_mask |=3D (1 << i); + } + } + + if (completed_mask) { + u->reg.is =3D FIELD_DP32(u->reg.is, IS, UTMRCS, 1); + ufs_irq_check(u); + } +} + static void ufs_write_reg(UfsHc *u, hwaddr offset, uint32_t data, unsigned= size) { switch (offset) { @@ -880,10 +989,16 @@ static void ufs_write_reg(UfsHc *u, hwaddr offset, ui= nt32_t data, unsigned size) case A_MCQCONFIG: u->reg.mcqconfig =3D data; break; - case A_UTRLCLR: case A_UTMRLDBR: + ufs_process_tmr(u, data); + break; case A_UTMRLCLR: + u->reg.utmrldbr &=3D ~data; + break; case A_UTMRLRSR: + u->reg.utmrlrsr =3D data; + break; + case A_UTRLCLR: trace_ufs_err_unsupport_register_offset(offset); break; default: --=20 2.55.0.1007.g17ff1f9808-goog