get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2194920/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2194920,
    "url": "http://patchwork.ozlabs.org/api/patches/2194920/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260210091018.1553489-19-jamin_lin@aspeedtech.com/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260210091018.1553489-19-jamin_lin@aspeedtech.com>",
    "list_archive_url": null,
    "date": "2026-02-10T09:10:46",
    "name": "[v5,18/21] hw/i3c: Add Mock target",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "5af5ca4f6553768ff100a9c2be4a2c5f66f519d7",
    "submitter": {
        "id": 81768,
        "url": "http://patchwork.ozlabs.org/api/people/81768/?format=api",
        "name": "Jamin Lin",
        "email": "jamin_lin@aspeedtech.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260210091018.1553489-19-jamin_lin@aspeedtech.com/mbox/",
    "series": [
        {
            "id": 491625,
            "url": "http://patchwork.ozlabs.org/api/series/491625/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=491625",
            "date": "2026-02-10T09:10:19",
            "name": "i3c: aspeed: Add I3C support",
            "version": 5,
            "mbox": "http://patchwork.ozlabs.org/series/491625/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2194920/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2194920/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=aspeedtech.com header.i=@aspeedtech.com\n header.a=rsa-sha256 header.s=selector1 header.b=Xx4Fvhs0;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)",
            "dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=aspeedtech.com;"
        ],
        "Received": [
            "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4f9G5k0ggSz1xtV\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 10 Feb 2026 20:11:38 +1100 (AEDT)",
            "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1vpjm2-00022h-8J; Tue, 10 Feb 2026 04:11:10 -0500",
            "from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <jamin_lin@aspeedtech.com>)\n id 1vpjlx-0001l3-Ti; Tue, 10 Feb 2026 04:11:06 -0500",
            "from mail-koreacentralazlp170130006.outbound.protection.outlook.com\n ([2a01:111:f403:c40f::6] helo=SEYPR02CU001.outbound.protection.outlook.com)\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <jamin_lin@aspeedtech.com>)\n id 1vpjlv-0004kR-Je; Tue, 10 Feb 2026 04:11:05 -0500",
            "from TYPPR06MB8206.apcprd06.prod.outlook.com (2603:1096:405:383::19)\n by KUZPR06MB8268.apcprd06.prod.outlook.com (2603:1096:d10:62::15)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9587.19; Tue, 10 Feb\n 2026 09:10:46 +0000",
            "from TYPPR06MB8206.apcprd06.prod.outlook.com\n ([fe80::e659:1ead:77cb:f6d3]) by TYPPR06MB8206.apcprd06.prod.outlook.com\n ([fe80::e659:1ead:77cb:f6d3%3]) with mapi id 15.20.9587.017; Tue, 10 Feb 2026\n 09:10:46 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=EgkkoIVtJpNXPZk2S7cmlR6Q1t9ZB6UuppE+b60yZVA58gmQlyPuqS6FKt0JHH1TxltjLszMF/2yd9Mf3Pe4c7kaHTuzfXCPu9XfZsa0qUZ9n/XvVK8S41hwPMtMlWtU2eda0dvUMHwQOc9Z3OPqtFv0qHwRh5+/jmFrP7kXHJsm2XyHwNi/9eZUiEyriJpIQBpsXEFpRkJnCkFuPfF0gniIdXnb6SrvrU+s+Qvs958NSvC9xhv2Hfaf4ZHv76vBMb8JwCuR2NmA7rX2Ev3hHctSsKVElZJu1xJ8hAAt6zBa4DLL6ED8+w5m7JNjTe870p1hiznxfjyJ8x9IWlBb1A==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector10001;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=GZjFS/hdvT8y2d1p3xi33JUio+UqLSU4JtKs354VCAg=;\n b=zHfDgRVpBXBcloIU5LEOzL0VsALbMbkuPLgXESYbqSqbXa2i5i35OEk0qJv/oJWiQtcMwHyEUM49yUlsCQrBGm53i1kV8uuXAmNuXgXXdA4X8qxezR+TM67YcV6+MqjMvcyyIqUlVKtLq4MJhoZR+pzvMlIz1bNy1JcT5LVXYAWtmM8xG2P0GpmQOL0M3z2PKd9WWDQsuRNxpj8P0h3mtZsHqpmRyaMSfH92BWSvtV4TYSCeBXcFnFPJCo2FzjR4RO3c3DCWsaIZQnuGYBZN3o9VKaGlUAuPH8y4umCNZLKTJw1uR+Nftd26OgK53oBiwpQSj4YcyGzjDKjEfxmWDA==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=aspeedtech.com; dmarc=pass action=none\n header.from=aspeedtech.com; dkim=pass header.d=aspeedtech.com; arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=aspeedtech.com;\n s=selector1;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=GZjFS/hdvT8y2d1p3xi33JUio+UqLSU4JtKs354VCAg=;\n b=Xx4Fvhs0zAzpQwpX8v0dl97+IzJVCq855/jF1fg9IJc9/UFljM7ht1s3ZQyM8trHzcNL+qVULdm+wEIrjZrSwS9H1s0t8gN/OANHotzhUkvX3eLcFUDSXf/PgKAxfNTqT0r2KRidTZk9VAoENFUOInEab796v58vqcGlV8NF/zjwuTuHb6g6axqWEN1oJwTbesa9CLDmAoYTx/YfcChHj//uuHaiZ+0HRpg2qyJ2mJOX2FCOVatK18TkSJA3YWOne5QUwO/ikRZzWsLHVW33q1RO9Jt5m1IPvpOH4I9EI/yn4WiC2mxv56qfZEUgg2ypiC/qBs2dBnef+9wp0Xz2dQ==",
        "From": "Jamin Lin <jamin_lin@aspeedtech.com>",
        "To": "Paolo Bonzini <pbonzini@redhat.com>,\n Peter Maydell <peter.maydell@linaro.org>,\n =?iso-8859-1?q?C=E9dric_Le_Goater?= <clg@kaod.org>,\n Steven Lee <steven_lee@aspeedtech.com>, Troy Lee <leetroy@gmail.com>,\n Andrew Jeffery <andrew@codeconstruct.com.au>, Joel Stanley <joel@jms.id.au>,\n\t=?iso-8859-1?q?Marc-Andr=E9_Lureau?= <marcandre.lureau@redhat.com>,\n\t=?iso-8859-1?q?Daniel_P=2E_Berrang=E9?= <berrange@redhat.com>,\n\t=?iso-8859-1?q?Philippe_Mathieu-Daud=E9?= <philmd@linaro.org>,\n \"open list:All patches CC here\" <qemu-devel@nongnu.org>,\n  \"open list:ARM TCG CPUs\" <qemu-arm@nongnu.org>",
        "CC": "Jamin Lin <jamin_lin@aspeedtech.com>, Troy Lee <troy_lee@aspeedtech.com>,\n Kane Chen <kane_chen@aspeedtech.com>, \"nabihestefan@google.com\"\n <nabihestefan@google.com>, Joe Komlodi <komlodi@google.com>, Titus Rwantare\n <titusr@google.com>, Patrick Venture <venture@google.com>",
        "Subject": "[PATCH v5 18/21] hw/i3c: Add Mock target",
        "Thread-Topic": "[PATCH v5 18/21] hw/i3c: Add Mock target",
        "Thread-Index": "AQHcmm0kEufGdnpVB0yRA+lK+teccg==",
        "Date": "Tue, 10 Feb 2026 09:10:46 +0000",
        "Message-ID": "<20260210091018.1553489-19-jamin_lin@aspeedtech.com>",
        "References": "<20260210091018.1553489-1-jamin_lin@aspeedtech.com>",
        "In-Reply-To": "<20260210091018.1553489-1-jamin_lin@aspeedtech.com>",
        "Accept-Language": "zh-TW, en-US",
        "Content-Language": "en-US",
        "X-MS-Has-Attach": "",
        "X-MS-TNEF-Correlator": "",
        "authentication-results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=aspeedtech.com header.i=@aspeedtech.com\n header.a=rsa-sha256 header.s=selector1 header.b=Xx4Fvhs0;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)",
            "dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=aspeedtech.com;"
        ],
        "x-ms-publictraffictype": "Email",
        "x-ms-traffictypediagnostic": "TYPPR06MB8206:EE_|KUZPR06MB8268:EE_",
        "x-ms-office365-filtering-correlation-id": "56b3074b-9bf8-433d-b191-08de688446a6",
        "x-ms-exchange-senderadcheck": "1",
        "x-ms-exchange-antispam-relay": "0",
        "x-microsoft-antispam": "BCL:0;\n ARA:13230040|366016|7416014|376014|1800799024|38070700021|921020;",
        "x-microsoft-antispam-message-info": "=?iso-8859-1?q?ahi8bgcammQAeTqFLZZGXTG8yR?=\n\t=?iso-8859-1?q?jpupwgJIEcc9qj1sx1POy+CGjfb6ahknZ+1sc6Ghc3WIW4lD078Jf3vgtb3g?=\n\t=?iso-8859-1?q?MQaKzz2i55LCRj080ap6NH/dchFzXWJGb2WxkQbaf3z/OF9sl5gPiSsV7tfl?=\n\t=?iso-8859-1?q?E1vKYjJS4idpJIGDvo5a1IxDZUhqCvTb2MY6npmAk6TWNLUL/Y1wiuKpxJOl?=\n\t=?iso-8859-1?q?DE1QLEQiJMN6n18xVvsBxhY4h0euNNQqJMkqss+50xO+vtHHgiQ/axGV171w?=\n\t=?iso-8859-1?q?NSg9NcuMXPeg5rUttyy/AeviIxePOr5lanILyeUGQa53/ZrT0lTtSxTqeLkQ?=\n\t=?iso-8859-1?q?ezY9xUEW1iPkgSJ8PtpPVierXstEtqthu2DpYFnqJTEQ9+fcB2MNqhGPVEZb?=\n\t=?iso-8859-1?q?7FZS9aYz9k+jt/KWGSaRa8q4tl1VLnciJ+Yb494Kjn/8Lo9QAOmvjIQv7JYq?=\n\t=?iso-8859-1?q?lkOBjjBTWAEeD9+cMWUqznQpuiLn91YKUtHHIJhiwotHIJo2NAs2Cs4rjcgR?=\n\t=?iso-8859-1?q?c20qY3mOveP6l1c++eRjs1BpkJuzoUSwvBh8YwbUVltWIcFW9rVSX1htlLUR?=\n\t=?iso-8859-1?q?8v7s+WHdNT/IjyhalCwk12nPOclq53e7jbualMSlPBw+vG+rO1uXEQjMnqxm?=\n\t=?iso-8859-1?q?zbqorlEbVnl3Si2dQdphAKgY3uM+WKRFl+TM7JETB+q9yr1Ski7EKtbsmasg?=\n\t=?iso-8859-1?q?FINc8wEpBs681Ripz/O/EMAV7GmpaQl3+pkxHrEyyiSkvQZv+HIjNo2v7VO6?=\n\t=?iso-8859-1?q?lNfL9dqj1NAtSCvHn3JC+Xf5XNLjGyisWt3sEmnYjav3mj5xFwllv7itM1+J?=\n\t=?iso-8859-1?q?7xfwJnwT7n0YuFiRvcQbIpFlXJw3C/XUXQvsX7mWdJC7TpI2/N5+y6WH0H6I?=\n\t=?iso-8859-1?q?fsUwE0bFiFiL7lt754fGreCbwJ4VgqW/hlTNdCfMMooU/XE1ddp/CjQRST7r?=\n\t=?iso-8859-1?q?/1Hhb5MCr29de7rpVJpj45PYBqAKng884iyw2d4x/0MerOSP6oGQUub2awqy?=\n\t=?iso-8859-1?q?JEq5G8Ns71H7avqihNruqOPj/Sl5oFFLNC8jHyvl4a7A6RgKZ7K/ze4llSmd?=\n\t=?iso-8859-1?q?spsA+m7ZO0HzPrrBzjLr0nQ/VJkYb3H7V+120lW5EXfyiI2AmkfiND2m3xNb?=\n\t=?iso-8859-1?q?NoSx0mCiCv+kjGAG/l+tZ8Zpxptdx6WFBJILnvjHOmluxAzhI5/19h/PGlOs?=\n\t=?iso-8859-1?q?pcvGMEpOFr4+5x5Mha6NPhc5wtdFMQPg23VNXFZve3fVcr/H83zYc+tqxaoN?=\n\t=?iso-8859-1?q?NAfMNOkcKqrIU6QUq7AAuFv13ocDh2VfvEAG+kYLAHIOWp4GVqZNuX+ELr5V?=\n\t=?iso-8859-1?q?eRvA8zFq1F8CgD/GGAgP618YxEBecgXVFrd5TeOvwHDuuxVfkJRH+I5JAIui?=\n\t=?iso-8859-1?q?KQjpEv97iOk53Amw/ky3cowtnVXj+omxvw5chmgmrP0ue6bguOW4jewMcTaV?=\n\t=?iso-8859-1?q?iWS9FPOhF7/7/kOEINbrjdj+r9z6IXiPZ6Zp9dJgAgtIHIuCfFD0LB5A42xd?=\n\t=?iso-8859-1?q?0Q5Hv5bXMhBy2EDORFy1ox0OubmdPUdD2+COVpOxnDIBpVu3ymOhyXMp2cES?=\n\t=?iso-8859-1?q?T2O64u22HPJYtYBoNwASLRFplEX68BIrC7LdL5RHBPzspYotE9rck7oZQRdA?=\n\t=?iso-8859-1?q?Ebddx8vkj4ll2NoJb2m2cjed4MI13YyQs9tjmeikZ/D82WA1elbiVJHQ/QJc?=\n\t=?iso-8859-1?q?9ER9qjmWDxxqFXEibn?=",
        "x-forefront-antispam-report": "CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;\n IPV:NLI; SFV:NSPM; H:TYPPR06MB8206.apcprd06.prod.outlook.com; PTR:; CAT:NONE;\n SFS:(13230040)(366016)(7416014)(376014)(1800799024)(38070700021)(921020);\n DIR:OUT; SFP:1102;",
        "x-ms-exchange-antispam-messagedata-chunkcount": "1",
        "x-ms-exchange-antispam-messagedata-0": "=?iso-8859-1?q?Mn5TqFXR8OAfiMWQaNC3/Lt?=\n\t=?iso-8859-1?q?FqlIUWuYJsoyQ1lD+oPM+g5EoLmksNkMsR3uSDH6x+7MRxAhWO2zmmkOvKSF?=\n\t=?iso-8859-1?q?JA9i0awitPJ1Kg6e9VHyqbekhlS8sB2/aPmfBpDxCFiH9ey1pq7blDVIQZM4?=\n\t=?iso-8859-1?q?p8RLGVTLnOuUrzXhTeoyaRWSotgDwDzmMOtjgaWA3f9Oodl8POe/KghhCGKq?=\n\t=?iso-8859-1?q?BPOLwvlt5UNdEDLbRnU/+PC88F4MYB/v4+la9GRNKimgd7dGXFYHmfloLfyp?=\n\t=?iso-8859-1?q?cXjQeLaxKXb7hI1rKiEy4urf21zmfTLs2SXrl3/W1bdJ7P20OJdHL3x0Lj8P?=\n\t=?iso-8859-1?q?eQMLv83geL3rUn38ITwHHWhsP0zGrSctciiGOxvTjIiS7Nkqa5a71iEak6My?=\n\t=?iso-8859-1?q?fo/XB1CaGb/3D7X1SSX82/g3HNtb5E1AFgoD6lRyBaYAGC5r8mGR+BH+qBJZ?=\n\t=?iso-8859-1?q?eG7DiN42eEzLLwZ/h46cq2sXFl9YuX/2D4OmxDazhVJNBa72JHabdV8KEn06?=\n\t=?iso-8859-1?q?+Z5PF4U7CryS3Zpq1fvAaqG6WhHyW1NKhBANpAD/4UwuM0+q13SBdQpf63m1?=\n\t=?iso-8859-1?q?effFDQOMu90jT314wFgMBhWRisIeqL5WYafVqhhrWnUkfpdKjrTgr1rzUOjr?=\n\t=?iso-8859-1?q?YHTlNOoe6vLgZYfqlaxZ/tCn9lYpMpEk4K8kURn0bjVx4K46rK+SSSxL2VYO?=\n\t=?iso-8859-1?q?NRRuQjQytaUhWxKnBAo2IGDJbVqFox6W01LPJIN9r4u2Jj0Ma8zR996ik+Fh?=\n\t=?iso-8859-1?q?mfPSm+zbMA9JE3A4VrBnfidEmR2pe7tWxp3iM7EQn0liz/XOPHfX85/qplAu?=\n\t=?iso-8859-1?q?vi7DonNzCstimGWH4Rx2c52U0c7cgGhe+JaXHS2vkf7SS0UrTPQZ/n34vEn2?=\n\t=?iso-8859-1?q?tbRQLruOZHrHxNkw8aNAxvEifiRoQ3oNEpYnqEq6c9gQBm1BmL2I/Ar7YLaV?=\n\t=?iso-8859-1?q?cJedSIMkiaraV4DQLncuuIVJZZ9Zn1n1oiXOSHKmCYirsd88mqjH6rOOdhoS?=\n\t=?iso-8859-1?q?+/eDww0GdjVwUSxASSoPPO4nKoey7NLkBdvl/gMpGiDgeUUdEwkak3s/WX9L?=\n\t=?iso-8859-1?q?hzc/2o1+xJVr4ONZP21tAXCBe7E11ksC4ktvYzIlqChKR6AMSq+dq7h0bXHa?=\n\t=?iso-8859-1?q?6VMAms9XP0ABFLX/GQAgRHd8UeeVH0sWjWt7QT+5Vrek9Bhe0UaAHwRztgyg?=\n\t=?iso-8859-1?q?xUPQAlZGCboPi9MrGtPYYCJ8oBqMWBf844wSqjR16nCh5iOBRtDTEpPe9own?=\n\t=?iso-8859-1?q?69hHFJMg8hXs3uQVIh7bYZ1JNTSsgDvV5hFGACEKaWLeCgdoFGcPozf/caP6?=\n\t=?iso-8859-1?q?fhtIG2QH7+je8v5jbTcpTw3111b4Ggu1+hMm7CdZHFf540lNB35EHzsbVoQJ?=\n\t=?iso-8859-1?q?UjCvIu4pYPRZJgrSZxTznKtGbubOJw3P/2qqn2WRBqpvkq6MqS/Pae6kpMKx?=\n\t=?iso-8859-1?q?8Q7rKRRa3ePARlXVEYvozkcxGDzAqV4Fth0ZFmsBjIyuSKzDFBZRYesABEWB?=\n\t=?iso-8859-1?q?KdnRlSyESLoxBIjXVx0RhiHGTtZ63lEodLTs0knN3nXGgLmE51z2Ve2DiBJD?=\n\t=?iso-8859-1?q?vBvgGQb6NLsZpeBM/X18BogJE+hEjUsDIVlI9MFRos55B4jrZOVnDLb7UXkJ?=\n\t=?iso-8859-1?q?uDgxjU3VbRIZdxmK0ig6GoZir3BOtsSwoQvlaPEv3viWXz91LqikQjkEuMEj?=\n\t=?iso-8859-1?q?HC4z0v8GkT+V7NhliLFVeK6UGP3QJRZgcBSpkS5zCgzizV3e7K+Xus4jfDiG?=\n\t=?iso-8859-1?q?NqrrX/5XXwjEbPfZjpkcmfWa/uhx9WdRAu0TlK+tN4UinCQ=3D=3D?=",
        "Content-Type": "text/plain; charset=\"iso-8859-1\"",
        "Content-Transfer-Encoding": "quoted-printable",
        "MIME-Version": "1.0",
        "X-OriginatorOrg": "aspeedtech.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Internal",
        "X-MS-Exchange-CrossTenant-AuthSource": "TYPPR06MB8206.apcprd06.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 56b3074b-9bf8-433d-b191-08de688446a6",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "10 Feb 2026 09:10:46.2976 (UTC)",
        "X-MS-Exchange-CrossTenant-fromentityheader": "Hosted",
        "X-MS-Exchange-CrossTenant-id": "43d4aa98-e35b-4575-8939-080e90d5a249",
        "X-MS-Exchange-CrossTenant-mailboxtype": "HOSTED",
        "X-MS-Exchange-CrossTenant-userprincipalname": "\n i+nfbjOfc87Ir0Jbziha/m6kkRhPBVbwEo/nT2qRZd7L7maSmCsbXIs5MyMbNfEb65zfarJFjGTaumO6o2IED4RnyL/yF1LcvQ2ZW+A2BDk=",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "KUZPR06MB8268",
        "Received-SPF": "pass client-ip=2a01:111:f403:c40f::6;\n envelope-from=jamin_lin@aspeedtech.com;\n helo=SEYPR02CU001.outbound.protection.outlook.com",
        "X-Spam_score_int": "-20",
        "X-Spam_score": "-2.1",
        "X-Spam_bar": "--",
        "X-Spam_report": "(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n SPF_HELO_PASS=-0.001,\n SPF_PASS=-0.001 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 <qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"
    },
    "content": "Adds a simple i3c device to be used for testing in lieu of a real\ndevice.\n\nThe mock target supports the following features:\n- A buffer that users can read and write to.\n- CCC support for commonly used CCCs when probing devices on an I3C bus.\n- IBI sending upon receiving a user-defined byte.\n\nSigned-off-by: Joe Komlodi <komlodi@google.com>\nReviewed-by: Titus Rwantare <titusr@google.com>\nReviewed-by: Patrick Venture <venture@google.com>\nReviewed-by: Jamin Lin <jamin_lin@aspeedtech.com>\nSigned-off-by: Jamin Lin <jamin_lin@aspeedtech.com>\n---\n include/hw/i3c/mock-i3c-target.h |  52 ++++++\n hw/i3c/mock-i3c-target.c         | 298 +++++++++++++++++++++++++++++++\n hw/i3c/Kconfig                   |  10 ++\n hw/i3c/meson.build               |   1 +\n hw/i3c/trace-events              |  10 ++\n 5 files changed, 371 insertions(+)\n create mode 100644 include/hw/i3c/mock-i3c-target.h\n create mode 100644 hw/i3c/mock-i3c-target.c",
    "diff": "diff --git a/include/hw/i3c/mock-i3c-target.h b/include/hw/i3c/mock-i3c-target.h\nnew file mode 100644\nindex 0000000000..8c6003ae8b\n--- /dev/null\n+++ b/include/hw/i3c/mock-i3c-target.h\n@@ -0,0 +1,52 @@\n+#ifndef MOCK_I3C_TARGET_H_\n+#define MOCK_I3C_TARGET_H_\n+\n+/*\n+ * Mock I3C Device\n+ *\n+ * Copyright (c) 2025 Google LLC\n+ *\n+ * The mock I3C device can be thought of as a simple EEPROM. It has a buffer,\n+ * and the pointer in the buffer is reset to 0 on an I3C STOP.\n+ * To write to the buffer, issue a private write and send data.\n+ * To read from the buffer, issue a private read.\n+ *\n+ * The mock target also supports sending target interrupt IBIs.\n+ * To issue an IBI, set the 'ibi-magic-num' property to a non-zero number, and\n+ * send that number in a private transaction. The mock target will issue an IBI\n+ * after 1 second.\n+ *\n+ * It also supports a handful of CCCs that are typically used when probing I3C\n+ * devices.\n+ *\n+ * SPDX-License-Identifier: GPL-2.0-or-later\n+ */\n+\n+#include \"qemu/osdep.h\"\n+#include \"qemu/timer.h\"\n+#include \"hw/i3c/i3c.h\"\n+\n+#define TYPE_MOCK_I3C_TARGET \"mock-i3c-target\"\n+OBJECT_DECLARE_SIMPLE_TYPE(MockI3cTargetState, MOCK_I3C_TARGET)\n+\n+struct MockI3cTargetState {\n+    I3CTarget parent_obj;\n+\n+    /* General device state */\n+    bool can_ibi;\n+    QEMUTimer qtimer;\n+    size_t p_buf;\n+    uint8_t *buf;\n+\n+    /* For Handing CCCs. */\n+    bool in_ccc;\n+    I3CCCC curr_ccc;\n+    uint8_t ccc_byte_offset;\n+\n+    struct {\n+        uint32_t buf_size;\n+        uint8_t ibi_magic;\n+    } cfg;\n+};\n+\n+#endif\ndiff --git a/hw/i3c/mock-i3c-target.c b/hw/i3c/mock-i3c-target.c\nnew file mode 100644\nindex 0000000000..875cd7c7d0\n--- /dev/null\n+++ b/hw/i3c/mock-i3c-target.c\n@@ -0,0 +1,298 @@\n+/*\n+ * Mock I3C Device\n+ *\n+ * Copyright (c) 2025 Google LLC\n+ *\n+ * The mock I3C device can be thought of as a simple EEPROM. It has a buffer,\n+ * and the pointer in the buffer is reset to 0 on an I3C STOP.\n+ * To write to the buffer, issue a private write and send data.\n+ * To read from the buffer, issue a private read.\n+ *\n+ * The mock target also supports sending target interrupt IBIs.\n+ * To issue an IBI, set the 'ibi-magic-num' property to a non-zero number, and\n+ * send that number in a private transaction. The mock target will issue an IBI\n+ * after 1 second.\n+ *\n+ * It also supports a handful of CCCs that are typically used when probing I3C\n+ * devices.\n+ *\n+ * SPDX-License-Identifier: GPL-2.0-or-later\n+ */\n+\n+#include \"qemu/osdep.h\"\n+#include \"qemu/log.h\"\n+#include \"trace.h\"\n+#include \"hw/i3c/i3c.h\"\n+#include \"hw/i3c/mock-i3c-target.h\"\n+#include \"hw/core/irq.h\"\n+#include \"hw/core/qdev-properties.h\"\n+#include \"qapi/error.h\"\n+#include \"qemu/module.h\"\n+\n+#define IBI_DELAY_NS (1 * 1000 * 1000)\n+\n+static uint32_t mock_i3c_target_rx(I3CTarget *i3c, uint8_t *data,\n+                                   uint32_t num_to_read)\n+{\n+    MockI3cTargetState *s = MOCK_I3C_TARGET(i3c);\n+    uint32_t i;\n+\n+    /* Bounds check. */\n+    if (s->p_buf == s->cfg.buf_size) {\n+        return 0;\n+    }\n+\n+    for (i = 0; i < num_to_read; i++) {\n+        data[i] = s->buf[s->p_buf];\n+        trace_mock_i3c_target_rx(data[i]);\n+        s->p_buf++;\n+        if (s->p_buf == s->cfg.buf_size) {\n+            break;\n+        }\n+    }\n+\n+    /* Return the number of bytes we're sending to the controller. */\n+    return i;\n+}\n+\n+static void mock_i3c_target_ibi_timer_start(MockI3cTargetState *s)\n+{\n+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);\n+    timer_mod(&s->qtimer, now + IBI_DELAY_NS);\n+}\n+\n+static int mock_i3c_target_tx(I3CTarget *i3c, const uint8_t *data,\n+                              uint32_t num_to_send, uint32_t *num_sent)\n+{\n+    MockI3cTargetState *s = MOCK_I3C_TARGET(i3c);\n+    int ret;\n+    uint32_t to_write;\n+\n+    if (s->cfg.ibi_magic && num_to_send == 1 && s->cfg.ibi_magic == *data) {\n+        mock_i3c_target_ibi_timer_start(s);\n+        return 0;\n+    }\n+\n+    /* Bounds check. */\n+    if (num_to_send + s->p_buf > s->cfg.buf_size) {\n+        to_write = s->cfg.buf_size - s->p_buf;\n+        ret = -1;\n+    } else {\n+        to_write = num_to_send;\n+        ret = 0;\n+    }\n+    for (uint32_t i = 0; i < to_write; i++) {\n+        trace_mock_i3c_target_tx(data[i]);\n+        s->buf[s->p_buf] = data[i];\n+        s->p_buf++;\n+    }\n+    return ret;\n+}\n+\n+static int mock_i3c_target_event(I3CTarget *i3c, enum I3CEvent event)\n+{\n+    MockI3cTargetState *s = MOCK_I3C_TARGET(i3c);\n+\n+    trace_mock_i3c_target_event(event);\n+    if (event == I3C_STOP) {\n+        s->in_ccc = false;\n+        s->curr_ccc = 0;\n+        s->ccc_byte_offset = 0;\n+        s->p_buf = 0;\n+    }\n+\n+    return 0;\n+}\n+\n+static int mock_i3c_target_handle_ccc_read(I3CTarget *i3c, uint8_t *data,\n+                                           uint32_t num_to_read,\n+                                           uint32_t *num_read)\n+{\n+    MockI3cTargetState *s = MOCK_I3C_TARGET(i3c);\n+\n+    switch (s->curr_ccc) {\n+    case I3C_CCCD_GETMXDS:\n+        /* Default data rate for I3C. */\n+        while (s->ccc_byte_offset < num_to_read) {\n+            if (s->ccc_byte_offset >= 2) {\n+                break;\n+            }\n+            data[s->ccc_byte_offset] = 0;\n+            *num_read = s->ccc_byte_offset;\n+            s->ccc_byte_offset++;\n+        }\n+        break;\n+    case I3C_CCCD_GETCAPS:\n+        /* Support I3C version 1.1.x, no other features. */\n+        while (s->ccc_byte_offset < num_to_read) {\n+            if (s->ccc_byte_offset >= 2) {\n+                break;\n+            }\n+            if (s->ccc_byte_offset == 0) {\n+                data[s->ccc_byte_offset] = 0;\n+            } else {\n+                data[s->ccc_byte_offset] = 0x01;\n+            }\n+            *num_read = s->ccc_byte_offset;\n+            s->ccc_byte_offset++;\n+        }\n+        break;\n+    case I3C_CCCD_GETMWL:\n+    case I3C_CCCD_GETMRL:\n+        /* MWL/MRL is MSB first. */\n+        while (s->ccc_byte_offset < num_to_read) {\n+            if (s->ccc_byte_offset >= 2) {\n+                break;\n+            }\n+            data[s->ccc_byte_offset] = (s->cfg.buf_size &\n+                                        (0xff00 >> (s->ccc_byte_offset * 8))) >>\n+                                        (8 - (s->ccc_byte_offset * 8));\n+            s->ccc_byte_offset++;\n+            *num_read = num_to_read;\n+        }\n+        break;\n+    case I3C_CCC_ENTDAA:\n+    case I3C_CCCD_GETPID:\n+    case I3C_CCCD_GETBCR:\n+    case I3C_CCCD_GETDCR:\n+        /* Nothing to do. */\n+        break;\n+    default:\n+        qemu_log_mask(LOG_GUEST_ERROR, \"Unhandled CCC 0x%.2x\\n\", s->curr_ccc);\n+        return -1;\n+    }\n+\n+    trace_mock_i3c_target_handle_ccc_read(*num_read, num_to_read);\n+    return 0;\n+}\n+\n+static int mock_i3c_target_handle_ccc_write(I3CTarget *i3c, const uint8_t *data,\n+                                            uint32_t num_to_send,\n+                                            uint32_t *num_sent)\n+{\n+    MockI3cTargetState *s = MOCK_I3C_TARGET(i3c);\n+\n+    if (!s->curr_ccc) {\n+        s->in_ccc = true;\n+        s->curr_ccc = *data;\n+        trace_mock_i3c_target_new_ccc(s->curr_ccc);\n+    }\n+\n+    *num_sent = 1;\n+    switch (s->curr_ccc) {\n+    case I3C_CCC_ENEC:\n+    case I3C_CCCD_ENEC:\n+        s->can_ibi = true;\n+        break;\n+    case I3C_CCC_DISEC:\n+    case I3C_CCCD_DISEC:\n+        s->can_ibi = false;\n+        break;\n+    case I3C_CCC_ENTDAA:\n+    case I3C_CCC_SETAASA:\n+    case I3C_CCC_RSTDAA:\n+    case I3C_CCCD_SETDASA:\n+    case I3C_CCCD_GETPID:\n+    case I3C_CCCD_GETBCR:\n+    case I3C_CCCD_GETDCR:\n+    case I3C_CCCD_GETMWL:\n+    case I3C_CCCD_GETMRL:\n+    case I3C_CCCD_GETMXDS:\n+    case I3C_CCCD_GETCAPS:\n+        /* Nothing to do. */\n+        break;\n+    default:\n+        qemu_log_mask(LOG_GUEST_ERROR, \"Unhandled CCC 0x%.2x\\n\", s->curr_ccc);\n+        return -1;\n+    }\n+\n+    trace_mock_i3c_target_handle_ccc_write(*num_sent, num_to_send);\n+    return 0;\n+}\n+\n+static void mock_i3c_target_do_ibi(MockI3cTargetState *s)\n+{\n+    if (!s->can_ibi) {\n+        return;\n+    }\n+\n+    trace_mock_i3c_target_do_ibi(s->parent_obj.address, true);\n+    int nack = i3c_target_send_ibi(&s->parent_obj, s->parent_obj.address,\n+                                   /*is_recv=*/true);\n+    /* Getting NACKed isn't necessarily an error, just print it out. */\n+    if (nack) {\n+        trace_mock_i3c_target_do_ibi_nack(\"sending\");\n+    }\n+    nack = i3c_target_ibi_finish(&s->parent_obj, 0x00);\n+    if (nack) {\n+        trace_mock_i3c_target_do_ibi_nack(\"finishing\");\n+    }\n+}\n+\n+static void mock_i3c_target_timer_elapsed(void *opaque)\n+{\n+    MockI3cTargetState *s = MOCK_I3C_TARGET(opaque);\n+    timer_del(&s->qtimer);\n+    mock_i3c_target_do_ibi(s);\n+}\n+\n+static void mock_i3c_target_reset(I3CTarget *i3c)\n+{\n+    MockI3cTargetState *s = MOCK_I3C_TARGET(i3c);\n+    s->can_ibi = false;\n+}\n+\n+static void mock_i3c_target_realize(DeviceState *dev, Error **errp)\n+{\n+    MockI3cTargetState *s = MOCK_I3C_TARGET(dev);\n+    s->buf = g_new0(uint8_t, s->cfg.buf_size);\n+    mock_i3c_target_reset(&s->parent_obj);\n+}\n+\n+static void mock_i3c_target_init(Object *obj)\n+{\n+    MockI3cTargetState *s = MOCK_I3C_TARGET(obj);\n+    s->can_ibi = false;\n+\n+    /* For IBIs. */\n+    timer_init_ns(&s->qtimer, QEMU_CLOCK_VIRTUAL, mock_i3c_target_timer_elapsed,\n+                  s);\n+}\n+\n+static const Property remote_i3c_props[] = {\n+    /* The size of the internal buffer. */\n+    DEFINE_PROP_UINT32(\"buf-size\", MockI3cTargetState, cfg.buf_size, 0x100),\n+    /*\n+     * If the mock target receives this number, it will issue an IBI after\n+     * 1 second. Disabled if the IBI magic number is 0.\n+     */\n+    DEFINE_PROP_UINT8(\"ibi-magic-num\", MockI3cTargetState, cfg.ibi_magic, 0x00),\n+};\n+\n+static void mock_i3c_target_class_init(ObjectClass *klass, const void *data)\n+{\n+    DeviceClass *dc = DEVICE_CLASS(klass);\n+    I3CTargetClass *k = I3C_TARGET_CLASS(klass);\n+\n+    dc->realize = mock_i3c_target_realize;\n+    k->event = mock_i3c_target_event;\n+    k->recv = mock_i3c_target_rx;\n+    k->send = mock_i3c_target_tx;\n+    k->handle_ccc_read = mock_i3c_target_handle_ccc_read;\n+    k->handle_ccc_write = mock_i3c_target_handle_ccc_write;\n+\n+    device_class_set_props(dc, remote_i3c_props);\n+}\n+\n+static const TypeInfo mock_i3c_target_types[] = {\n+    {\n+        .name          = TYPE_MOCK_I3C_TARGET,\n+        .parent        = TYPE_I3C_TARGET,\n+        .instance_size = sizeof(MockI3cTargetState),\n+        .instance_init = mock_i3c_target_init,\n+        .class_init    = mock_i3c_target_class_init,\n+    },\n+};\n+\n+DEFINE_TYPES(mock_i3c_target_types)\n+\ndiff --git a/hw/i3c/Kconfig b/hw/i3c/Kconfig\nindex ecec77d6fc..d5c6d4049b 100644\n--- a/hw/i3c/Kconfig\n+++ b/hw/i3c/Kconfig\n@@ -3,3 +3,13 @@ config I3C\n \n config DW_I3C\n     bool\n+\n+config I3C_DEVICES\n+    # Device group for i3c devices which can reasonably be user-plugged to any\n+    # board's i3c bus.\n+    bool\n+\n+config MOCK_I3C_TARGET\n+    bool\n+    select I3C\n+    default y if I3C_DEVICES\ndiff --git a/hw/i3c/meson.build b/hw/i3c/meson.build\nindex 83d75e7d5c..e614b18712 100644\n--- a/hw/i3c/meson.build\n+++ b/hw/i3c/meson.build\n@@ -2,4 +2,5 @@ i3c_ss = ss.source_set()\n i3c_ss.add(when: 'CONFIG_I3C', if_true: files('core.c'))\n i3c_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_i3c.c'))\n i3c_ss.add(when: 'CONFIG_DW_I3C', if_true: files('dw-i3c.c'))\n+i3c_ss.add(when: 'CONFIG_MOCK_I3C_TARGET', if_true: files('mock-i3c-target.c'))\n system_ss.add_all(when: 'CONFIG_I3C', if_true: i3c_ss)\ndiff --git a/hw/i3c/trace-events b/hw/i3c/trace-events\nindex 39f33d9a50..9e58edec99 100644\n--- a/hw/i3c/trace-events\n+++ b/hw/i3c/trace-events\n@@ -36,3 +36,13 @@ legacy_i2c_recv(uint8_t byte) \"Legacy I2C recv 0x%\" PRIx8\n legacy_i2c_send(uint8_t byte) \"Legacy I2C send 0x%\" PRIx8\n legacy_i2c_start_transfer(uint8_t address, bool is_recv) \"Legacy I2C START with address 0x%\" PRIx8 \" is_recv=%d\"\n legacy_i2c_end_transfer(void) \"Legacy I2C STOP\"\n+\n+# mock-target.c\n+mock_i3c_target_rx(uint8_t byte) \"I3C mock target read 0x%\" PRIx8\n+mock_i3c_target_tx(uint8_t byte) \"I3C mock target write 0x%\" PRIx8\n+mock_i3c_target_event(uint8_t event) \"I3C mock target event 0x%\" PRIx8\n+mock_i3c_target_handle_ccc_read(uint32_t num_read, uint32_t num_to_read) \"I3C mock target read %\" PRId32 \"/%\" PRId32 \" bytes\"\n+mock_i3c_target_new_ccc(uint8_t ccc) \"I3C mock target handle CCC 0x%\" PRIx8\n+mock_i3c_target_handle_ccc_write(uint32_t num_sent, uint32_t num_to_send) \"I3C mock target send %\" PRId32 \"/%\" PRId32 \" bytes\"\n+mock_i3c_target_do_ibi(uint8_t address, bool is_recv) \"I3C mock target IBI with address 0x%\" PRIx8 \" RnW=%d\"\n+mock_i3c_target_do_ibi_nack(const char *reason) \"NACKed from controller when %s target interrupt\"\n",
    "prefixes": [
        "v5",
        "18/21"
    ]
}