From patchwork Tue Dec 17 08:22:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13911362 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.15]) (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 983DA1D63C4 for ; Tue, 17 Dec 2024 08:22:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423749; cv=none; b=ZA3VGu7aFqOgE7OKs3zHuY8aVNJp8Xgry2PYViGdLOQuInc5rjjiZIyynpZg2fPY4mrvm49czcrlSss/17Z4XL3SXmXVM4nalN3qZ+VUFBfl8EB88kUhLHk9DdNYRPbixiWFW7/Tngr2pb3kFYCfwiPHVtoSSh7Xu0QKXporhv0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423749; c=relaxed/simple; bh=FafJbNr5gNji0JWMn3wCkxlMVr3ikCRi8cfU0fIuhVU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=po1kLkmsEXaBCTyer4vn46RIyx7miVtRN10VpmlRrWVfZn+J/PWcY/Ib2Ri4Jtnt0bgpCqIl/6Goapp98n7DUvdmpED/iHg7P//aq0C1vF6rSj2vaAmm7dDVCmrG5ky3OWK1KrG77nVXyaGGa4BF1WXT5lbhDWCRqscym3wGIZQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=GWWDfQ0l; arc=none smtp.client-ip=198.175.65.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="GWWDfQ0l" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734423748; x=1765959748; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=FafJbNr5gNji0JWMn3wCkxlMVr3ikCRi8cfU0fIuhVU=; b=GWWDfQ0lUGpIgG89dQxnJ/S+GWef3BM9HuPURAprdMawSy+uU4Tc38Ey GssDAmn3rpapEiVd6aWctsy22DKh4cVir4GHwZVvdIAxkhLMTMilTCovn HMhjCOAUdaktpEp2+D2LywFRg5GdCDlmlUgMOtvO/Tf57aFoWRQ3/ynZT nFXpSn/zhRfxstiTpJyoXCxojypLN8N49sckSN7Vz6VTzbMa+o5cSs7hP u03IbxM6H3six73DRSok7EkRpMnoVbAzWesmrQsDoRVHNEIyg9lr4zNPL 9lwhX9V+iDte1zTZZ/KvqdnOulQgJgR3Nrev0e6evaFPGpu1/ywVhpQ4C A==; X-CSE-ConnectionGUID: d1tlKY3DSxCSrK8wARdbWg== X-CSE-MsgGUID: v5T9msWfSqiaZXIGCay/QQ== X-IronPort-AV: E=McAfee;i="6700,10204,11288"; a="38511434" X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="38511434" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa107.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Dec 2024 00:22:26 -0800 X-CSE-ConnectionGUID: 5n4JeqK+TJykR/8I2P6jIQ== X-CSE-MsgGUID: hV59TtAPQ06EWtq25+LqDA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="102063224" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa005.fm.intel.com with ESMTP; 17 Dec 2024 00:22:24 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 0384F331; Tue, 17 Dec 2024 10:22:22 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Mika Westerberg Subject: [PATCH 01/12] thunderbolt: Drop doubled empty line from ctl.h Date: Tue, 17 Dec 2024 10:22:11 +0200 Message-ID: <20241217082222.528602-2-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241217082222.528602-1-mika.westerberg@linux.intel.com> References: <20241217082222.528602-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 No functional changes. Signed-off-by: Mika Westerberg --- drivers/thunderbolt/ctl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/thunderbolt/ctl.h b/drivers/thunderbolt/ctl.h index bf930a191472..7e08ca8f0895 100644 --- a/drivers/thunderbolt/ctl.h +++ b/drivers/thunderbolt/ctl.h @@ -140,5 +140,4 @@ int tb_cfg_write(struct tb_ctl *ctl, const void *buffer, u64 route, u32 port, enum tb_cfg_space space, u32 offset, u32 length); int tb_cfg_get_upstream_port(struct tb_ctl *ctl, u64 route); - #endif From patchwork Tue Dec 17 08:22:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13911361 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 5D4F01CF2A2 for ; Tue, 17 Dec 2024 08:22:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423747; cv=none; b=WpT1ky8DUsJ2vJjykS/2pd3pnYoSKAL/Y0NOvtR6AmCCwLJtlQRNhKYNJklUxMYfo2c3pmVLVwEZkrTXd6dFD1mWG3JwEet3DzoRMbkRTsI23HE+zBfDOMQ9Zbts0U1PTgRqPVxGaYuIKAwYgVDfC9/pt+xgq15urtKJu0icrH8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423747; c=relaxed/simple; bh=tSeYYk8Dl6uqq7IrWAQI2z3d1xDJrdfjAAuT2X1jt3E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KtNTIiB7bVl+kx3U3IObEus+ifHSmQMSJiQ8sqGnckPAab9tI/tQrhV+fCa70PuRdJMZj0H6BdsH0za5DScZkixgEr2e7R98ECk4EyvvEv2MGX4WLnunt+aLFWgVY6tzQYcC8GT0o2N9bqkXwkqtysCMzU76+5cDagTFGhteUFY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=bf3hXQiQ; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="bf3hXQiQ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734423746; x=1765959746; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tSeYYk8Dl6uqq7IrWAQI2z3d1xDJrdfjAAuT2X1jt3E=; b=bf3hXQiQH9SsW29YeQX93EEawAFymnLJ2senQE8rPDXvUQgCzFKAXJbQ bcPy5Hyyq7CPIau9bBeDNYUCfnjjJc71PGK7b6FT6ZeJbyZggcPPomMMa D9LGTCVQAahY6omG3mkYbxadtKY9jP+uFB7wgocy9bwan56hUoX/2aLcb /DFNenoh7ODQfvmaWeEVhCRCAiGWCNsVghiIaCKI2CsXptKbpbdrLfLho YDoMShgWqnmJlEjY6ThVidwhDotTZXnvSs0fJfOEg+8KPNFARNJ2JY/ww skXKzdQz5c4N8v6Qx9GO1zlYJVFmjqexYYmzqom0s3sHwQBR1eVXVqesy Q==; X-CSE-ConnectionGUID: 3zEQA3P0TBKbineMoUJgog== X-CSE-MsgGUID: dBkCn8C/QOan7QxID/i0ug== X-IronPort-AV: E=McAfee;i="6700,10204,11288"; a="34992565" X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="34992565" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Dec 2024 00:22:25 -0800 X-CSE-ConnectionGUID: b9auWSt+RQ68mzSuYOitAw== X-CSE-MsgGUID: XtBon4oAQZqWDAT0F42o1Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="98037623" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa009.fm.intel.com with ESMTP; 17 Dec 2024 00:22:24 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id E9CA2A1; Tue, 17 Dec 2024 10:22:22 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Mika Westerberg Subject: [PATCH 02/12] thunderbolt: Log config space when invalid config space reply is received Date: Tue, 17 Dec 2024 10:22:12 +0200 Message-ID: <20241217082222.528602-3-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241217082222.528602-1-mika.westerberg@linux.intel.com> References: <20241217082222.528602-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 For debugging purposes helps to see the config space that was being accessed. Signed-off-by: Mika Westerberg --- drivers/thunderbolt/ctl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/thunderbolt/ctl.c b/drivers/thunderbolt/ctl.c index 4bdb2d45e0bf..fd40cda1e53f 100644 --- a/drivers/thunderbolt/ctl.c +++ b/drivers/thunderbolt/ctl.c @@ -265,7 +265,7 @@ static struct tb_cfg_result parse_header(const struct ctl_pkg *pkg, u32 len, return res; } -static void tb_cfg_print_error(struct tb_ctl *ctl, +static void tb_cfg_print_error(struct tb_ctl *ctl, enum tb_cfg_space space, const struct tb_cfg_result *res) { WARN_ON(res->err != 1); @@ -279,8 +279,8 @@ static void tb_cfg_print_error(struct tb_ctl *ctl, * Invalid cfg_space/offset/length combination in * cfg_read/cfg_write. */ - tb_ctl_dbg(ctl, "%llx:%x: invalid config space or offset\n", - res->response_route, res->response_port); + tb_ctl_dbg(ctl, "%llx:%x: invalid config space (%u) or offset\n", + res->response_route, res->response_port, space); return; case TB_CFG_ERROR_NO_SUCH_PORT: /* @@ -1072,7 +1072,7 @@ static int tb_cfg_get_error(struct tb_ctl *ctl, enum tb_cfg_space space, res->tb_error == TB_CFG_ERROR_INVALID_CONFIG_SPACE) return -ENODEV; - tb_cfg_print_error(ctl, res); + tb_cfg_print_error(ctl, space, res); if (res->tb_error == TB_CFG_ERROR_LOCK) return -EACCES; From patchwork Tue Dec 17 08:22:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13911364 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 06FD41DAC93 for ; Tue, 17 Dec 2024 08:22:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423750; cv=none; b=eUPhLAlTuuq1wrOnCV0WOg/kOA2gToEhg+yrfCWIkZByZbJWYeZhDXxALfpca1D62M8ha+0RmpeaeHOBAgQn/GIz/S7P24aGKC1H+bWRnJv0MK0DN+IJOnx8oizAFJX+F7BIflrh0azieJbuPF/Zs/I/rOaEV31WpeFEtvZoxLo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423750; c=relaxed/simple; bh=aDI2PARWshFzqSbNn2kZVW9I7Gseb9t5J7c7x3bcOR4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ISFemqMENVBtBrzYwP50tQzN4GfofcuDyuYOU2qVFMi06iy1n7yd4orqg1CBrmZGof+8nHW03IQegwRFajVnxRG+ynPP9WLt5/LbXu7hvlIyOVaedh7UdQ4+dm0Wy1WnTRkmW6YpEGTsgZ8aCRGM9aejKuwjYcgUCVMpWVoN+pk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=FGp5U9FK; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="FGp5U9FK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734423748; x=1765959748; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=aDI2PARWshFzqSbNn2kZVW9I7Gseb9t5J7c7x3bcOR4=; b=FGp5U9FKzce48dLPeyC5WzO1x9+jjQ1nbaacDfA/okHvK+hv0wy0Hvue icLrNnuMQzBqN7CrPjIy9UYsTb2nx+BpWNWpZ74mSiAuWJlWhJ7W2CfBn txgdHAzIyvt4xZsF2+CvjAyZeidSFxXIIGgr8yM6ZUmojaAOcxKd0kmGt zG/cFHnmB2/OlFdvmona7xp7z6ia/WL+jKCk9WhKQ6SWASwyz9KRvQAEC hVzZCN5P+P7s8kZ1bpvgYU2ZUbaDD7JXUu5m5DZC7fjLH0TQszKoqNeYC rBjW0CPrEGe4tYPay6nr47jrjPI/QA/VvH0OwMrcskl890Uq3ej0B+TfT w==; X-CSE-ConnectionGUID: NcL+1t99TXqwQoXuAAnESg== X-CSE-MsgGUID: EV1pU3JhTcukzamfrH0cLw== X-IronPort-AV: E=McAfee;i="6700,10204,11288"; a="34992568" X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="34992568" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Dec 2024 00:22:25 -0800 X-CSE-ConnectionGUID: CWsXBAKPTR6+er/5AcHkeQ== X-CSE-MsgGUID: cujgWNh1QBKpjLBqNhxnpQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="98037625" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa009.fm.intel.com with ESMTP; 17 Dec 2024 00:22:24 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 08772329; Tue, 17 Dec 2024 10:22:22 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Mika Westerberg Subject: [PATCH 03/12] thunderbolt: Debug log an invalid config space reply just once Date: Tue, 17 Dec 2024 10:22:13 +0200 Message-ID: <20241217082222.528602-4-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241217082222.528602-1-mika.westerberg@linux.intel.com> References: <20241217082222.528602-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 These can mess up the debug log if a router does not implement the config space register blocks fully and we are reading registers through debugfs. To avoid this, just log it once. Signed-off-by: Mika Westerberg --- drivers/thunderbolt/ctl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/thunderbolt/ctl.c b/drivers/thunderbolt/ctl.c index fd40cda1e53f..dc1f456736dc 100644 --- a/drivers/thunderbolt/ctl.c +++ b/drivers/thunderbolt/ctl.c @@ -70,6 +70,9 @@ struct tb_ctl { #define tb_ctl_dbg(ctl, format, arg...) \ dev_dbg(&(ctl)->nhi->pdev->dev, format, ## arg) +#define tb_ctl_dbg_once(ctl, format, arg...) \ + dev_dbg_once(&(ctl)->nhi->pdev->dev, format, ## arg) + static DECLARE_WAIT_QUEUE_HEAD(tb_cfg_request_cancel_queue); /* Serializes access to request kref_get/put */ static DEFINE_MUTEX(tb_cfg_request_lock); @@ -279,8 +282,8 @@ static void tb_cfg_print_error(struct tb_ctl *ctl, enum tb_cfg_space space, * Invalid cfg_space/offset/length combination in * cfg_read/cfg_write. */ - tb_ctl_dbg(ctl, "%llx:%x: invalid config space (%u) or offset\n", - res->response_route, res->response_port, space); + tb_ctl_dbg_once(ctl, "%llx:%x: invalid config space (%u) or offset\n", + res->response_route, res->response_port, space); return; case TB_CFG_ERROR_NO_SUCH_PORT: /* From patchwork Tue Dec 17 08:22:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13911363 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.15]) (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 0B5DF1DAC95 for ; Tue, 17 Dec 2024 08:22:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423749; cv=none; b=tBMmcpiAQ3gi3DCv4SsUed6W4NmJEjrAP6vGDTkyqX0c6ABKsma/K7EiPGWYMq8OX5SXIzANbTK5lYk6HWo4UkGua5j3ZnySJ9r6dQXU2BQ2hrewSiqtAh2dQBX8cJGdMA+wXJ463p6xeD6NgC6J+at1TP1DjPrnxM022EGSrc4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423749; c=relaxed/simple; bh=rm+XfwCDb1w4MEyXlwYaAx7AGaBaxxUlyDBzqRIYnfA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WwBd9gFtHq9Cz4J9cv3CV168TRBJPfTJkZMD2WcVkjKq7+7na/GbO1lllE+WOSDtZcQTId3XNVxt3xV3YhzuB1g5ameYccmFmV+q2WpB+pgYWXxD3iB9W1wSA/nyzMWqG4sQQhuUOzayM9j7rBH/zofohyAfvd3812iIZEMA0No= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=b6ZS3EWI; arc=none smtp.client-ip=198.175.65.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="b6ZS3EWI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734423748; x=1765959748; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=rm+XfwCDb1w4MEyXlwYaAx7AGaBaxxUlyDBzqRIYnfA=; b=b6ZS3EWIeEpTjdmdvp00/aMth+KjZ36hfrIdSXqaMEfbtgTfIzM4T9PI fiy1Uvw4NMUzlLx4CRKT4duXx1PGjVQB82WfuponMyjl+AcftMY+mSWUx 9GaKx8imurPT8dipZuTSqPRRILQKqNFFWnYlavikulfCAt0CCDO0GvEiK GOkRTua9RgAZQ12PbRmWgtfGRP+nm6ySlg4aqsKhyO5QUF7YHffsEKD6E ITl8mlPqMGXaA1jj0ZCvrwD/Csbhl7pn0avBQ2IlLH+GxDZ4u0eBijJcM h5+yzZA4s7xLEaOi0baVxnL+ZvKRWZnlRKNwQAmmhscCkame8l1BqOa76 g==; X-CSE-ConnectionGUID: ixLAekflSy6+zPrfkn0T6w== X-CSE-MsgGUID: MIe5Q4f/QcWGt+L6eZtK5Q== X-IronPort-AV: E=McAfee;i="6700,10204,11288"; a="38511438" X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="38511438" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa107.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Dec 2024 00:22:26 -0800 X-CSE-ConnectionGUID: sWRdy1z4QASGtm2zGTkyeg== X-CSE-MsgGUID: YwiAPW0iT1qx6MYT2/Mt9w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="102063226" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa005.fm.intel.com with ESMTP; 17 Dec 2024 00:22:24 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 0DF7C3B7; Tue, 17 Dec 2024 10:22:23 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Mika Westerberg Subject: [PATCH 04/12] thunderbolt: Increase DPRX capabilities read timeout Date: Tue, 17 Dec 2024 10:22:14 +0200 Message-ID: <20241217082222.528602-5-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241217082222.528602-1-mika.westerberg@linux.intel.com> References: <20241217082222.528602-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Some graphics drivers such as i915 support runtime power management and if there is nothing connected at the moment they will runtime suspend to save power. At least i915 is polling for new connections every 10 seconds if the hardware does support sending PME. To allow i915 and other graphics from detect the just established DisplayPort tunnel allow the DPRX capabilities read to take up to 12 seconds. Signed-off-by: Mika Westerberg --- drivers/thunderbolt/tunnel.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index 41cf6378ad25..f9e75c221fef 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -1186,9 +1186,12 @@ static int tb_dp_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, * return that bandwidth (it may be smaller than the * reduced one). According to VESA spec, the DPRX * negotiation shall compete in 5 seconds after tunnel - * established. We give it 100ms extra just in case. + * established. Since at least i915 can runtime suspend + * if there is nothing connected, and that it polls any + * new connections every 10 seconds, we use 12 seconds + * here. */ - ret = tb_dp_wait_dprx(tunnel, 5100); + ret = tb_dp_wait_dprx(tunnel, 12000); if (ret) return ret; ret = tb_dp_read_cap(tunnel, DP_COMMON_CAP, &rate, &lanes); From patchwork Tue Dec 17 08:22:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13911370 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 42FCE1DB377 for ; Tue, 17 Dec 2024 08:22:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423765; cv=none; b=tYKxvRhPe8jmWLt/Wl0SxiHAsBwt7b0mFlFx53I8BczoUDgg5N9SdSMkIn7CByUS0+ebICjtqVMFnesV1wpxO8zzuYpRFYBGwOi1OjTIrX4TmQCqSCbfDVPX4SVMaMlEe483HK1YV/3kKK4V9R8W437dGBrHZZKbQsM/Z7FNahk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423765; c=relaxed/simple; bh=kMjB35+F5oAxOIdNTc7ZiKso2QeKr+3q9AQLhrjld4o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZHLfGlkwIfw4kpaGA5x/Ujli6qCeunKtmQmvpl7On0P8TMmcLataJArUoQPXSJ2sIU4BxECJsdSDXNOO0EP6/UshXe22g90R7RwK3Cl/ebo54vHvdMxVoxkM5y5geGx4oM1+wRJMJkC5zchzeZHWiXtqRwf5ScyqJiIWeffnD8w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=E5d4UqZ+; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="E5d4UqZ+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734423764; x=1765959764; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kMjB35+F5oAxOIdNTc7ZiKso2QeKr+3q9AQLhrjld4o=; b=E5d4UqZ+V6VqBPcW77Wkkr4whcD5h/0TImmtY/AVK1exhXs0OHWqZJZV 9Yu9dub/hHW9x4Lk5HXdgghaI/X1YzRoB4Z/oOwicNOJ5THd8aV4pjetC aQMARm9IVzoRG3mRglD/xMnS0/Wr5OtmvcE5uzGaYLPPC8I59G0orQoEZ V579bxDr5g41iqlUOUmVmk3Ef9JfTFHsiZNT3MYu3xYAWk5yb+yoC42nO X38kWHfFbPfu4BDuSX+a1T3pspLeno+g8RlESWRLbFNJuPZvGci0hN48N TeZ4Y7W/xVS2X17fhdz5C1U26JogTXvIpd0a1LiKO21VRGdJ80/Dm3OHz g==; X-CSE-ConnectionGUID: Ahvp3XPPRY+5CUr3FbfONQ== X-CSE-MsgGUID: xKzszB4tTNG67RHJo8zkOA== X-IronPort-AV: E=McAfee;i="6700,10204,11288"; a="34992608" X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="34992608" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Dec 2024 00:22:37 -0800 X-CSE-ConnectionGUID: /g4cm6rtSfKZVszxuG2stg== X-CSE-MsgGUID: w00r6r6rSF27qWmFFcqt8A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="98037683" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa009.fm.intel.com with ESMTP; 17 Dec 2024 00:22:26 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 1B90A703; Tue, 17 Dec 2024 10:22:23 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Mika Westerberg Subject: [PATCH 05/12] thunderbolt: Make tb_tunnel_one_dp() return void Date: Tue, 17 Dec 2024 10:22:15 +0200 Message-ID: <20241217082222.528602-6-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241217082222.528602-1-mika.westerberg@linux.intel.com> References: <20241217082222.528602-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The boolean return value is never used so we can make this return void instead. Signed-off-by: Mika Westerberg --- drivers/thunderbolt/tb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index a7c6919fbf97..7595ca00b6b8 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -1864,7 +1864,7 @@ static struct tb_port *tb_find_dp_out(struct tb *tb, struct tb_port *in) return NULL; } -static bool tb_tunnel_one_dp(struct tb *tb, struct tb_port *in, +static void tb_tunnel_one_dp(struct tb *tb, struct tb_port *in, struct tb_port *out) { int available_up, available_down, ret, link_nr; @@ -1954,7 +1954,7 @@ static bool tb_tunnel_one_dp(struct tb *tb, struct tb_port *in, * TMU mode to HiFi for CL0s to work. */ tb_increase_tmu_accuracy(tunnel); - return true; + return; err_deactivate: tb_tunnel_deactivate(tunnel); @@ -1971,8 +1971,6 @@ static bool tb_tunnel_one_dp(struct tb *tb, struct tb_port *in, pm_runtime_put_autosuspend(&out->sw->dev); pm_runtime_mark_last_busy(&in->sw->dev); pm_runtime_put_autosuspend(&in->sw->dev); - - return false; } static void tb_tunnel_dp(struct tb *tb) From patchwork Tue Dec 17 08:22:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13911365 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.15]) (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 2132A1DBB24 for ; Tue, 17 Dec 2024 08:22:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423750; cv=none; b=DUUJ2HlDWGIMGBDV1nExgdvFpGWhdEw/1LaVhvGgU1C8uqjUxvZU5o+w5uuIZwBhd7ioyakn10T4oQ/snP1SoUTiBCKCSatael/pu18d4Lt2XLLsTkQsqDyMLZ+ccWtSopKMQ1yWMcDLe/lBFWm4rBmt532P2eAp4HWxxHlsaSg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423750; c=relaxed/simple; bh=L71qdzPBIxHeeF9NnhXTAoGkbxyD6X5/SFu56xfZxzM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h/MsvkEnIlb0/iVwT2v3U0K5PjwX2XD70R8xnQkJhJn1UKXXifdO453mYd2NMvv51zSRSJC57u8m7YHTaIkS6sLYrk+lzVHcjTDjbuSGLSjIwN2ERKC+saZP7b/pXhYJNno5JWrhEcijyAKwGF9rDub0UsuX+C9PH45C7YuLG/w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=EySr4Zw0; arc=none smtp.client-ip=198.175.65.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="EySr4Zw0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734423749; x=1765959749; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=L71qdzPBIxHeeF9NnhXTAoGkbxyD6X5/SFu56xfZxzM=; b=EySr4Zw0mImefWk6oUOB/efv+OuDePF5V7GvfeXJbxudnkSZXt+OswM8 kYB87U2EHFRjor/GepKpvBuxF5cNAKjm0iL1g6auOUvehkXuR7I4RX9b1 LnXuNMOmL7OyXpxa5KIJgFNAUWIGYayNJsfIYvWDT3nQh7kKm781nU6cO js5UCkejbVuwUDssMd06v/70RZqWTks6FWuvcoZTOIK1VpJzqxDMGM+tV wNB9jlAA/4MBi5B/KcYzavSCSNdx6z5ihl3JCtgkUio7A6RgCddU9s5ei HWD1XHvSPMp/O7TCKat0liO7HV7m1jO9O/kH64YC1unlccT/LvdbelP5T Q==; X-CSE-ConnectionGUID: ZLbGkPy4Q/mQvLqKumB0xQ== X-CSE-MsgGUID: 8KLIjCauRrqANW8xDURscg== X-IronPort-AV: E=McAfee;i="6700,10204,11288"; a="38511450" X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="38511450" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa107.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Dec 2024 00:22:28 -0800 X-CSE-ConnectionGUID: IY56RhhoSDmKjCAIv9dbSA== X-CSE-MsgGUID: Q+M3hvTwQ/6Id8X7DpEwDA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="102063247" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa005.fm.intel.com with ESMTP; 17 Dec 2024 00:22:27 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 24D9740B; Tue, 17 Dec 2024 10:22:23 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Mika Westerberg Subject: [PATCH 06/12] thunderbolt: Show path name in debug log when path is deactivated Date: Tue, 17 Dec 2024 10:22:16 +0200 Message-ID: <20241217082222.528602-7-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241217082222.528602-1-mika.westerberg@linux.intel.com> References: <20241217082222.528602-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Similarly as we do when activating the path. Helps in debugging. Signed-off-by: Mika Westerberg --- drivers/thunderbolt/path.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c index f760e54cd9bd..e1a5f6e3d0b6 100644 --- a/drivers/thunderbolt/path.c +++ b/drivers/thunderbolt/path.c @@ -581,10 +581,10 @@ int tb_path_activate(struct tb_path *path) } } path->activated = true; - tb_dbg(path->tb, "path activation complete\n"); + tb_dbg(path->tb, "%s path activation complete\n", path->name); return 0; err: - tb_WARN(path->tb, "path activation failed\n"); + tb_WARN(path->tb, "%s path activation failed\n", path->name); return res; } From patchwork Tue Dec 17 08:22:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13911368 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.15]) (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 8C41F1DD54C for ; Tue, 17 Dec 2024 08:22:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423752; cv=none; b=lFzrvQbRMUYCOV50lvtP1NE64BoRd2RC7qM3Sd1tjhTJ7J7PMi2Kt5XG9lknVSPYYBJAyb6XROKKD0nfHnAoyyH44yg6tHA+cQhBiFs6pAfTxQetEARWw8Oq1We7t7ehwxk2yJ1L/BSh+mUH3XWekuZ5ydeS5NGjC0J9ZJJd2pU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423752; c=relaxed/simple; bh=OPaH7A4OdQ6wb6rrpdbQJ/9+xdqU/8OvlKDuvaN2t8Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HoCKLJppDrETWGS/DMDUoG0nA/Q0c49x9rwjeQ1G24C2SUqoN+xTNX9ufEEYJyDn2cVc/6ogxqptZtipiXkVIVnmXE9fdngtj7lHMHUc6V8KmcXmowalSKKG50qF30dK/DSUAYXyAHTMjwhP1JI0E1NfmyyHvCViv98RbVzQN1Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=btxWqCHi; arc=none smtp.client-ip=198.175.65.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="btxWqCHi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734423751; x=1765959751; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=OPaH7A4OdQ6wb6rrpdbQJ/9+xdqU/8OvlKDuvaN2t8Q=; b=btxWqCHi22hJEYvRL9qzDwNIuYKpmfOjbULs/UxUuLpymLG4xh81o23A 17EVtVXMDPpctpjAh+dxdgpCD+a1WphD+QxGVlKTlCIaYp3GSHWoc3o8C aMqc4swSNbEerMuKSayuO17cPEMMCuuGf2J8CfIAjnwpO11FyeEA019oc oHz2bjtk3LbV6AMZDk0Ufh8P1oVLRpQhQc+m4Hfc5EPIloOb2Fd6KCIIW c1Pyw1FCP/DiQr0xKpIPbTY3ki0fNBlVacnZx3Gu15uip6PNJqWgg1yAw NdKdeLE9F5H0F9cZCvSS224vVauLqCnlAen6QwB5cYh3d8VIX+SWFEoaN g==; X-CSE-ConnectionGUID: h7Dyyr2DTputA0JMBPWD6A== X-CSE-MsgGUID: AvstdKMoSFSXd+tbdyDlTQ== X-IronPort-AV: E=McAfee;i="6700,10204,11288"; a="38511454" X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="38511454" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa107.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Dec 2024 00:22:28 -0800 X-CSE-ConnectionGUID: 1NIAO6SYTWu3TBGaT4A30g== X-CSE-MsgGUID: lnuQS7KfRTi7OGy3wPiubg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="102063251" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa005.fm.intel.com with ESMTP; 17 Dec 2024 00:22:27 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 3292082E; Tue, 17 Dec 2024 10:22:23 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Mika Westerberg Subject: [PATCH 07/12] thunderbolt: Rework how tunnel->[init|deinit] hooks are called Date: Tue, 17 Dec 2024 10:22:17 +0200 Message-ID: <20241217082222.528602-8-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241217082222.528602-1-mika.westerberg@linux.intel.com> References: <20241217082222.528602-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The way these are called is not exactly symmetric as it is supposed to be: the former is called when tunnel is being activated and the latter is called when it is being released (not when it is being de-activated). Furthermore host-to-host (DMA) tunnels are abusing the ->deinit hook to clear out the credits. This makes it quite hard to follow what is being called and when. For these reasons rework the two "init" hooks to be called symmetrically and rename them accordingly. For the DMA one, add a new hook that is specifically used to run clean up for the tunnel when its memory is being released. Signed-off-by: Mika Westerberg --- drivers/thunderbolt/tunnel.c | 37 +++++++++++++++++++----------------- drivers/thunderbolt/tunnel.h | 13 +++++++++---- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index f9e75c221fef..83bd2043bab2 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -851,7 +851,7 @@ static int tb_dp_bandwidth_alloc_mode_enable(struct tb_tunnel *tunnel) return 0; } -static int tb_dp_init(struct tb_tunnel *tunnel) +static int tb_dp_pre_activate(struct tb_tunnel *tunnel) { struct tb_port *in = tunnel->src_port; struct tb_switch *sw = in->sw; @@ -877,7 +877,7 @@ static int tb_dp_init(struct tb_tunnel *tunnel) return tb_dp_bandwidth_alloc_mode_enable(tunnel); } -static void tb_dp_deinit(struct tb_tunnel *tunnel) +static void tb_dp_post_deactivate(struct tb_tunnel *tunnel) { struct tb_port *in = tunnel->src_port; @@ -1368,9 +1368,9 @@ struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in, if (!tunnel) return NULL; - tunnel->init = tb_dp_init; - tunnel->deinit = tb_dp_deinit; + tunnel->pre_activate = tb_dp_pre_activate; tunnel->activate = tb_dp_activate; + tunnel->post_deactivate = tb_dp_post_deactivate; tunnel->maximum_bandwidth = tb_dp_maximum_bandwidth; tunnel->allocated_bandwidth = tb_dp_allocated_bandwidth; tunnel->alloc_bandwidth = tb_dp_alloc_bandwidth; @@ -1464,9 +1464,9 @@ struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, if (!tunnel) return NULL; - tunnel->init = tb_dp_init; - tunnel->deinit = tb_dp_deinit; + tunnel->pre_activate = tb_dp_pre_activate; tunnel->activate = tb_dp_activate; + tunnel->post_deactivate = tb_dp_post_deactivate; tunnel->maximum_bandwidth = tb_dp_maximum_bandwidth; tunnel->allocated_bandwidth = tb_dp_allocated_bandwidth; tunnel->alloc_bandwidth = tb_dp_alloc_bandwidth; @@ -1623,7 +1623,7 @@ static void tb_dma_release_credits(struct tb_path_hop *hop) } } -static void tb_dma_deinit_path(struct tb_path *path) +static void tb_dma_destroy_path(struct tb_path *path) { struct tb_path_hop *hop; @@ -1631,14 +1631,14 @@ static void tb_dma_deinit_path(struct tb_path *path) tb_dma_release_credits(hop); } -static void tb_dma_deinit(struct tb_tunnel *tunnel) +static void tb_dma_destroy(struct tb_tunnel *tunnel) { int i; for (i = 0; i < tunnel->npaths; i++) { if (!tunnel->paths[i]) continue; - tb_dma_deinit_path(tunnel->paths[i]); + tb_dma_destroy_path(tunnel->paths[i]); } } @@ -1684,7 +1684,7 @@ struct tb_tunnel *tb_tunnel_alloc_dma(struct tb *tb, struct tb_port *nhi, tunnel->src_port = nhi; tunnel->dst_port = dst; - tunnel->deinit = tb_dma_deinit; + tunnel->destroy = tb_dma_destroy; credits = min_not_zero(dma_credits, nhi->sw->max_dma_credits); @@ -1796,7 +1796,7 @@ static int tb_usb3_max_link_rate(struct tb_port *up, struct tb_port *down) return min(up_max_rate, down_max_rate); } -static int tb_usb3_init(struct tb_tunnel *tunnel) +static int tb_usb3_pre_activate(struct tb_tunnel *tunnel) { tb_tunnel_dbg(tunnel, "allocating initial bandwidth %d/%d Mb/s\n", tunnel->allocated_up, tunnel->allocated_down); @@ -2027,7 +2027,7 @@ struct tb_tunnel *tb_tunnel_discover_usb3(struct tb *tb, struct tb_port *down, tb_tunnel_dbg(tunnel, "currently allocated bandwidth %d/%d Mb/s\n", tunnel->allocated_up, tunnel->allocated_down); - tunnel->init = tb_usb3_init; + tunnel->pre_activate = tb_usb3_pre_activate; tunnel->consumed_bandwidth = tb_usb3_consumed_bandwidth; tunnel->release_unused_bandwidth = tb_usb3_release_unused_bandwidth; @@ -2116,7 +2116,7 @@ struct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *tb, struct tb_port *up, tunnel->allocated_up = min(max_rate, max_up); tunnel->allocated_down = min(max_rate, max_down); - tunnel->init = tb_usb3_init; + tunnel->pre_activate = tb_usb3_pre_activate; tunnel->consumed_bandwidth = tb_usb3_consumed_bandwidth; tunnel->release_unused_bandwidth = tb_usb3_release_unused_bandwidth; @@ -2140,8 +2140,8 @@ void tb_tunnel_free(struct tb_tunnel *tunnel) if (!tunnel) return; - if (tunnel->deinit) - tunnel->deinit(tunnel); + if (tunnel->destroy) + tunnel->destroy(tunnel); for (i = 0; i < tunnel->npaths; i++) { if (tunnel->paths[i]) @@ -2192,8 +2192,8 @@ int tb_tunnel_restart(struct tb_tunnel *tunnel) } } - if (tunnel->init) { - res = tunnel->init(tunnel); + if (tunnel->pre_activate) { + res = tunnel->pre_activate(tunnel); if (res) return res; } @@ -2256,6 +2256,9 @@ void tb_tunnel_deactivate(struct tb_tunnel *tunnel) if (tunnel->paths[i] && tunnel->paths[i]->activated) tb_path_deactivate(tunnel->paths[i]); } + + if (tunnel->post_deactivate) + tunnel->post_deactivate(tunnel); } /** diff --git a/drivers/thunderbolt/tunnel.h b/drivers/thunderbolt/tunnel.h index 1a27ccd08b86..30c079fd121e 100644 --- a/drivers/thunderbolt/tunnel.h +++ b/drivers/thunderbolt/tunnel.h @@ -26,9 +26,13 @@ enum tb_tunnel_type { * tunnels may be %NULL or null adapter port instead. * @paths: All paths required by the tunnel * @npaths: Number of paths in @paths - * @init: Optional tunnel specific initialization - * @deinit: Optional tunnel specific de-initialization + * @pre_activate: Optional tunnel specific initialization called before + * activation. Can touch hardware. * @activate: Optional tunnel specific activation/deactivation + * @post_deactivate: Optional tunnel specific de-initialization called + * after deactivation. Can touch hardware. + * @destroy: Optional tunnel specific callback called when the tunnel + * memory is being released. Should not touch hardware. * @maximum_bandwidth: Returns maximum possible bandwidth for this tunnel * @allocated_bandwidth: Return how much bandwidth is allocated for the tunnel * @alloc_bandwidth: Change tunnel bandwidth allocation @@ -52,9 +56,10 @@ struct tb_tunnel { struct tb_port *dst_port; struct tb_path **paths; size_t npaths; - int (*init)(struct tb_tunnel *tunnel); - void (*deinit)(struct tb_tunnel *tunnel); + int (*pre_activate)(struct tb_tunnel *tunnel); int (*activate)(struct tb_tunnel *tunnel, bool activate); + void (*post_deactivate)(struct tb_tunnel *tunnel); + void (*destroy)(struct tb_tunnel *tunnel); int (*maximum_bandwidth)(struct tb_tunnel *tunnel, int *max_up, int *max_down); int (*allocated_bandwidth)(struct tb_tunnel *tunnel, int *allocated_up, From patchwork Tue Dec 17 08:22:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13911372 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 CFBF91DB92A for ; Tue, 17 Dec 2024 08:22:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423767; cv=none; b=t3yiJriQleWp8t3dRU5yZ/PyKCNxItN2zGZOmI7rTf9+B3ezOgmR9N+32AThgtlBA4fBqzYARI3jaw8wnDO51T1Mbv6eHo77DOrfizaL6et1yXmIUntw643uwVd4kGOyobjd7RUTUKUFc2TIlLdf/OkC3sBGzDPk/C0cPUfEVTY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423767; c=relaxed/simple; bh=Wu5RyFCpoQ9OOQp49JRuL/Q0pjWi7Zqp605zVnz3x6g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ieK4nU/+R+iM5bdaaLOt4T2ztYI+DztJ3t6uZUhNmuIfYQBwhPtjXwHzwwGUTcWzZelZV6LUXHIfbIU4LlFPXjIlV+IVq3xxkkNjdAjZtJQrxcERxrkiswFFHQ6+ReKJc4NXhumaN+6wJ+LEhSEbUDqVAbLvP51o304iOkxTyQU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=apja7WK9; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="apja7WK9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734423765; x=1765959765; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Wu5RyFCpoQ9OOQp49JRuL/Q0pjWi7Zqp605zVnz3x6g=; b=apja7WK9AVCvmzZp64VkGUvFrrlFLPQ1P4qvRK561KIo2bLsbMA5DUm1 bJlvy6F2ZhnMFvkaoIyPoTICvf2WJ1esumWA0nSjBGgGTBSH7xhDZt0Jw M13rHSCx7x9e0zZQPK6mDP7WdWRfKgslD++q/nVjQOP9j+rgzCNpYTY4/ EaiKEhPNZbUKl+EcWWx+ILp8rZxBPzczE2ltISZKDuTYgh/UTRjlAJZx/ G5LyxysFf2yc6/5sLGoBOGpRtdjfryfAcTFG4WN6X0bvkZxBXP8VfkOBJ T2phkncLZFR35KmkGrWYISI2s1l3SOfjMdvxpoJgNw1wQBAiFdYWnl1VA w==; X-CSE-ConnectionGUID: UekSacz8RV6jFPE1EzhSwQ== X-CSE-MsgGUID: TdCrk2sPQxS2Yl4vJ7r74A== X-IronPort-AV: E=McAfee;i="6700,10204,11288"; a="34992611" X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="34992611" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Dec 2024 00:22:37 -0800 X-CSE-ConnectionGUID: 8UCIO5DdTH6CvQ2kEf3DZA== X-CSE-MsgGUID: jdhv8WsCSB+qMlKnYGfY5w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="98037690" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa009.fm.intel.com with ESMTP; 17 Dec 2024 00:22:26 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 38DE5902; Tue, 17 Dec 2024 10:22:23 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Mika Westerberg Subject: [PATCH 08/12] thunderbolt: Drop tb_tunnel_restart() Date: Tue, 17 Dec 2024 10:22:18 +0200 Message-ID: <20241217082222.528602-9-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241217082222.528602-1-mika.westerberg@linux.intel.com> References: <20241217082222.528602-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 It is pretty much the same as tb_tunnel_activate() excepts does check for already activated paths. This is not needed anymore and makes it more streamlined so drop tb_tunnel_restart() in favour of tb_tunnel_activate(). Signed-off-by: Mika Westerberg --- drivers/thunderbolt/tb.c | 4 ++-- drivers/thunderbolt/tunnel.c | 27 +++------------------------ drivers/thunderbolt/tunnel.h | 1 - 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 7595ca00b6b8..53e4890e3198 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -3037,7 +3037,7 @@ static int tb_resume_noirq(struct tb *tb) /* Only need to do it once */ usb3_delay = 0; } - tb_tunnel_restart(tunnel); + tb_tunnel_activate(tunnel); } if (!list_empty(&tcm->tunnel_list)) { /* @@ -3147,7 +3147,7 @@ static int tb_runtime_resume(struct tb *tb) tb_free_invalid_tunnels(tb); tb_restore_children(tb->root_switch); list_for_each_entry_safe(tunnel, n, &tcm->tunnel_list, list) - tb_tunnel_restart(tunnel); + tb_tunnel_activate(tunnel); tb_switch_enter_redrive(tb->root_switch); tcm->hotplug_active = true; mutex_unlock(&tb->lock); diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index 83bd2043bab2..09619190c34a 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -2170,12 +2170,12 @@ bool tb_tunnel_is_invalid(struct tb_tunnel *tunnel) } /** - * tb_tunnel_restart() - activate a tunnel after a hardware reset - * @tunnel: Tunnel to restart + * tb_tunnel_activate() - activate a tunnel + * @tunnel: Tunnel to activate * * Return: 0 on success and negative errno in case if failure */ -int tb_tunnel_restart(struct tb_tunnel *tunnel) +int tb_tunnel_activate(struct tb_tunnel *tunnel) { int res, i; @@ -2218,27 +2218,6 @@ int tb_tunnel_restart(struct tb_tunnel *tunnel) return res; } -/** - * tb_tunnel_activate() - activate a tunnel - * @tunnel: Tunnel to activate - * - * Return: Returns 0 on success or an error code on failure. - */ -int tb_tunnel_activate(struct tb_tunnel *tunnel) -{ - int i; - - for (i = 0; i < tunnel->npaths; i++) { - if (tunnel->paths[i]->activated) { - tb_tunnel_WARN(tunnel, - "trying to activate an already activated tunnel\n"); - return -EINVAL; - } - } - - return tb_tunnel_restart(tunnel); -} - /** * tb_tunnel_deactivate() - deactivate a tunnel * @tunnel: Tunnel to deactivate diff --git a/drivers/thunderbolt/tunnel.h b/drivers/thunderbolt/tunnel.h index 30c079fd121e..3d3ab180cb9b 100644 --- a/drivers/thunderbolt/tunnel.h +++ b/drivers/thunderbolt/tunnel.h @@ -106,7 +106,6 @@ struct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *tb, struct tb_port *up, void tb_tunnel_free(struct tb_tunnel *tunnel); int tb_tunnel_activate(struct tb_tunnel *tunnel); -int tb_tunnel_restart(struct tb_tunnel *tunnel); void tb_tunnel_deactivate(struct tb_tunnel *tunnel); bool tb_tunnel_is_invalid(struct tb_tunnel *tunnel); bool tb_tunnel_port_on_path(const struct tb_tunnel *tunnel, From patchwork Tue Dec 17 08:22:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13911366 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.15]) (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 07E531DB938 for ; Tue, 17 Dec 2024 08:22:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423750; cv=none; b=ugbznDp1GhG68ASKa/o14VYbXcPZ/Ub+RIOJnEMz0J8AqSMHDlg4vM/6zze+dhsjxuLphPt7cgFWlKQQlFlRV/DoFWOMc8YHRfiqy1nDLNycUyYt5oW/s5+Z0KVQEnA8nuOX5ptvGJuWDTI+OYu5TGgde9YDqV8+JaCxHv9vsgM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423750; c=relaxed/simple; bh=YYtr0cuhOWs6ELaPPdDPDjxOZ2jg4tQU3j7NGvowirM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Xvgky6kw6hUgrq1IHRnaFIYWUwd00XJGD99ulDNCKt5x4QjN3KL1xu854cSmv21jDtjgVpAC+pt9/cqr6sjAeaMEMAjjRUX7O7kwIRkVEnWvdf8aYoTDPrAQMOkF6WNCOgkrLmn5bpK5Gsqg5DF/OC72YRXqpKy0rtaGQB6HrSk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=X+7TznOo; arc=none smtp.client-ip=198.175.65.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="X+7TznOo" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734423749; x=1765959749; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=YYtr0cuhOWs6ELaPPdDPDjxOZ2jg4tQU3j7NGvowirM=; b=X+7TznOowJlcIjGo0lkyx7+3rp4rXTN7zh7khiGV8ScyZLAPjqpmwoxd 08O6HgkeVwNIVwT7U4oySTwUr7FSIlFPVegxseGbqHhk/98oH3lFk5Fzw KIU13AEpzLPRe4/Y/GQRMLhZJhP9p16UY8yhytlvKupPbP6ZLZiCF90vE NZJOOmd4ruRNIlvTyOAoPEW4CZdao/vCAK8uzNnt8/grE7fW6cnD5Dnvm N3AsXko0HH9tSeWlkR74c2ZjLduYR00Yi5UXR5inkuxDF+Tks5XhROCBM tHNr0KN0MfoTixsnpzJ254KoNG7/N9q3Dp2iadAOV4DPk1ZEV5nyPPwIp w==; X-CSE-ConnectionGUID: uKV1QuW9T2uH7A3nCR1MkQ== X-CSE-MsgGUID: iIT/orcETzeulOfxpy9Z3g== X-IronPort-AV: E=McAfee;i="6700,10204,11288"; a="38511447" X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="38511447" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa107.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Dec 2024 00:22:28 -0800 X-CSE-ConnectionGUID: GZPaYkdMT5GNOeG59/7Mlw== X-CSE-MsgGUID: mVkfCSItQUW7aIz8lhGBmA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="102063245" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa005.fm.intel.com with ESMTP; 17 Dec 2024 00:22:27 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 44B68913; Tue, 17 Dec 2024 10:22:23 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Mika Westerberg Subject: [PATCH 09/12] thunderbolt: Pass reason to tb_dp_resource_unavailable() Date: Tue, 17 Dec 2024 10:22:19 +0200 Message-ID: <20241217082222.528602-10-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241217082222.528602-1-mika.westerberg@linux.intel.com> References: <20241217082222.528602-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Since we are going to call this also when DisplayPort tunnel establishment fails it is useful to have the reason logged. Signed-off-by: Mika Westerberg --- drivers/thunderbolt/tb.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 53e4890e3198..60454f9b9475 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -2088,17 +2088,18 @@ static void tb_switch_exit_redrive(struct tb_switch *sw) } } -static void tb_dp_resource_unavailable(struct tb *tb, struct tb_port *port) +static void tb_dp_resource_unavailable(struct tb *tb, struct tb_port *port, + const char *reason) { struct tb_port *in, *out; struct tb_tunnel *tunnel; if (tb_port_is_dpin(port)) { - tb_port_dbg(port, "DP IN resource unavailable\n"); + tb_port_dbg(port, "DP IN resource unavailable: %s\n", reason); in = port; out = NULL; } else { - tb_port_dbg(port, "DP OUT resource unavailable\n"); + tb_port_dbg(port, "DP OUT resource unavailable: %s\n", reason); in = NULL; out = port; } @@ -2404,7 +2405,7 @@ static void tb_handle_hotplug(struct work_struct *work) tb_xdomain_put(xd); tb_port_unconfigure_xdomain(port); } else if (tb_port_is_dpout(port) || tb_port_is_dpin(port)) { - tb_dp_resource_unavailable(tb, port); + tb_dp_resource_unavailable(tb, port, "adapter unplug"); } else if (!port->port) { tb_sw_dbg(sw, "xHCI disconnect request\n"); tb_switch_xhci_disconnect(sw); From patchwork Tue Dec 17 08:22:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13911369 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 30C9C155393 for ; Tue, 17 Dec 2024 08:22:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423763; cv=none; b=QBmAf08hZa0i4o6uizZYFJnWjOCi3gjCBKRPyvONnb+A3CyYwUbYRGS1Na1e9DGMXT8fViQnbeo6TC6BEjnhnC5+F/t4Zrjd9ggDmezZCI+Z32fwtZfmVW6HrR+JeqiSuMIogkjMVk60YQKR/BS88dX3hol+0TemCad9VoB4+sg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423763; c=relaxed/simple; bh=OBa0TP3jMBW3M8PfDmQBOl0C9sF3eiVp7SD02DFtGC8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u0IAHV8PNlo6AFfxvXmOiu38pPBn2rGoojOmEb7o0phjocSnCit6IuD0gY46jBj4yQCr33isJ9mlSR1N31nOoosRJFK3Umdg503sAzgeJm5CkeGO5Ko/5vqqkmZvAjD95uGpGqerAl5czYn3YiFcD5xnP34gvpBVoHvnADtO0+o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=evZszTbS; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="evZszTbS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734423762; x=1765959762; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=OBa0TP3jMBW3M8PfDmQBOl0C9sF3eiVp7SD02DFtGC8=; b=evZszTbSLpBD6zevoUIYslY7kqPS31LyiRq8IKpStO24C4SLtRnHjmol 7b5K8iYr+/1d+mmm3zzh+TFD6Zxp24oSCpI5sIOg3WIcEhfMahRDvRoHF 4CyyIZFRJUKLLysB434T5v5tQCnZjec82JxwU3TOxZt6FCluML1E9RN+g mf8Cd+UjePE5rkb9z3dycWVApichq/S6232mS52wnmm7GJVe+0POC7wlJ 56Jv/bIhRGNBDobFEzI6CbL5DQ7hdn8HUbZrWr7Ngdig9QZ1In/y1fLhB GR1k9WL1pU8hwqZsv/I3k/hYEpOr+9zTuO14rVrtTCV68822P8SqgZiDs g==; X-CSE-ConnectionGUID: kD3HfgTSQDWcujOwEAiZhw== X-CSE-MsgGUID: Ce5U097TQOyEcxUm5/LEuA== X-IronPort-AV: E=McAfee;i="6700,10204,11288"; a="34992602" X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="34992602" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Dec 2024 00:22:37 -0800 X-CSE-ConnectionGUID: 9Wz0lVYRQCaAKUzScFfniw== X-CSE-MsgGUID: ln9Zq9nXTNS6+svU/Q//Vg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="98037685" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa009.fm.intel.com with ESMTP; 17 Dec 2024 00:22:26 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 4B79E91A; Tue, 17 Dec 2024 10:22:23 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Mika Westerberg Subject: [PATCH 10/12] thunderbolt: Move forward declarations in one place Date: Tue, 17 Dec 2024 10:22:20 +0200 Message-ID: <20241217082222.528602-11-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241217082222.528602-1-mika.westerberg@linux.intel.com> References: <20241217082222.528602-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sometimes we need to have these but move them into one place so that the code is bit more understanable. Signed-off-by: Mika Westerberg --- drivers/thunderbolt/tb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 60454f9b9475..79ebf70f42e5 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -76,6 +76,7 @@ struct tb_hotplug_event { bool unplug; }; +static void tb_scan_port(struct tb_port *port); static void tb_handle_hotplug(struct work_struct *work); static void tb_queue_hotplug(struct tb *tb, u64 route, u8 port, bool unplug) @@ -1238,8 +1239,6 @@ static void tb_configure_link(struct tb_port *down, struct tb_port *up, tb_switch_configure_link(sw); } -static void tb_scan_port(struct tb_port *port); - /* * tb_scan_switch() - scan for and initialize downstream switches */ From patchwork Tue Dec 17 08:22:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13911367 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.15]) (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 A4F441DC1AF for ; Tue, 17 Dec 2024 08:22:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423751; cv=none; b=ugjPEQJn8JUWgwoSwu9ijcehMkkwrg01QwEqlOsd/B5xK/PAKGRyyx0hgKyzHkBul02rAcqTPozgpdfPp7QD+RE8NQPtfdwZ2rEsD1gsiGDCpnCRkmsqeIQTWbmdg7neyvLFt9WJUjk3svU2tkxD5Ks63dFhk8mIBP5Sc5n9rLI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423751; c=relaxed/simple; bh=WkXQnHqsnivLu1FZYtXzm47W5XdZHPbxuCE1F6Qi9O4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Kc7f2JdS/TbrLKWfftimpq2jYjETSvr44gz/wkKRyGRm2pW8x/nxXoaxPLCtyOoGMYzPB1eIVnlmQb3HT7n+8P4pnaTmCtSImToTh7AIVfEavmeKCyWxEXqtdOZ16KGglHPLCe1ThJGEK74Za5v/1AHW6OfBHrLW2FbIOPML63o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=mAIeBMF9; arc=none smtp.client-ip=198.175.65.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="mAIeBMF9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734423750; x=1765959750; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=WkXQnHqsnivLu1FZYtXzm47W5XdZHPbxuCE1F6Qi9O4=; b=mAIeBMF9O3AkPKRpFfsggI3zoZFUC1wT0GsByFd7Xx4qIsthoYPZSG1h 0JjPkHKrAFeGnYgNfVFjNj649AzgHlYmT9cOAWfLH88Iozjgdnb6rr+C5 8+TKAsB5tCepdcKD3o2OwdDvLbycd3f2ziLqXV+PCIp1n2GZR7BINAuXN ApqHoG+fVuinNE6wxaARdFmbuDrma7C3IjXLgNzZWHoGwwlfth0yzxAoG ywi/yGIcMMUjM1MQSwfT6h3kjzCfeM8h/0AVR7ZxdICrwptQy6E43fZJC 2reblvO19SPbtkg1b04ZPlJ2UcBT9qd7fwZ6m2aLgmzsQ7JCZbiw3iYLb A==; X-CSE-ConnectionGUID: Bj4fRSvDTwWO4JOYDI4cjw== X-CSE-MsgGUID: /SoeY5yxRFabQwkhxFoe1g== X-IronPort-AV: E=McAfee;i="6700,10204,11288"; a="38511452" X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="38511452" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa107.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Dec 2024 00:22:28 -0800 X-CSE-ConnectionGUID: 566nqk/YQa2ixLBL3RPicg== X-CSE-MsgGUID: Hy4usd2iRf6y5Ji+Nr9QXg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="102063249" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa005.fm.intel.com with ESMTP; 17 Dec 2024 00:22:27 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 5198B92D; Tue, 17 Dec 2024 10:22:23 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Mika Westerberg Subject: [PATCH 11/12] thunderbolt: Rework tb_tunnel_consumed_bandwidth() Date: Tue, 17 Dec 2024 10:22:21 +0200 Message-ID: <20241217082222.528602-12-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241217082222.528602-1-mika.westerberg@linux.intel.com> References: <20241217082222.528602-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Rework to avoid the goto as it only makes it confusing. Move logging to happen at the end so we can see all the tunnels this is being called. Signed-off-by: Mika Westerberg --- drivers/thunderbolt/tunnel.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index 09619190c34a..c625b5b84a7c 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -2361,26 +2361,20 @@ int tb_tunnel_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, { int up_bw = 0, down_bw = 0; - if (!tb_tunnel_is_active(tunnel)) - goto out; - - if (tunnel->consumed_bandwidth) { + if (tb_tunnel_is_active(tunnel) && tunnel->consumed_bandwidth) { int ret; ret = tunnel->consumed_bandwidth(tunnel, &up_bw, &down_bw); if (ret) return ret; - - tb_tunnel_dbg(tunnel, "consumed bandwidth %d/%d Mb/s\n", up_bw, - down_bw); } -out: if (consumed_up) *consumed_up = up_bw; if (consumed_down) *consumed_down = down_bw; + tb_tunnel_dbg(tunnel, "consumed bandwidth %d/%d Mb/s\n", up_bw, down_bw); return 0; } From patchwork Tue Dec 17 08:22:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 13911371 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 C0F271DA619 for ; Tue, 17 Dec 2024 08:22:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423766; cv=none; b=Aw6zmTseB+dwgJMWxP9fAGGjrMdgWxnCWs07Di+ftVSqcyA+2fEfqbtX7qRU8BdPHAs6u0Dq6tbrGpdZlMM2VijQ39H4PenStRaAT8OENdy9JWElyRdINLTWeMQbSiV7plcacuojZigcgRuvJzk3+sO27PbfkosKFZ8NnueRGhM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734423766; c=relaxed/simple; bh=/F91+/CiUKLP7E59tdXDFf5CcuBbhlJRsb0ZAN/tvVU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pyObn0SIg2/UdSbfUumimkWeAm5pQrt2GxpHWW886+cmbTAx75Lvk66XRnDreIfFBuKMy1CuILLQVXTY9MpY5zZh1JhpUWGhcHB1K9li7ANHo6QoCBfNPwI+U8hGTzttNHMth3hO5xT1cS/mlJNGANZn1ydQBgkUgO4buVDOi18= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=P3vt0um4; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="P3vt0um4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734423763; x=1765959763; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/F91+/CiUKLP7E59tdXDFf5CcuBbhlJRsb0ZAN/tvVU=; b=P3vt0um454JXCDTm6+BXOGH4Xqr2ZANG4gPGuc0fGzVjTqVdBPWA3hhJ hTUDWoM1wNembiYOy1+j+xVTLZl3xw66bw/rMPs7ndYB0ubuHWm0sJplZ zQ5FeQYtKhNNH62InFQgNVGk5wf6CG9m4ajUknx6wrY1j7EkiquTrhI8H 5SUFp8MRdWJl3l7If1nNASqBXvlTqWOAIqIcAA81HcQbWfHcQXiTYZp7p O7wacm+dGSVva1v+CrK0Z/IsQHrwqaHb3wa+2QWHm8Op/YZhZYRpup4s3 kz6VP54S4rA2kj9nHfgUDbeXQajqoGatY1ECc5nuNlLJj95KOoOBtq/Uz Q==; X-CSE-ConnectionGUID: 5xS6tf3vQ4q7nyV64v6/Ag== X-CSE-MsgGUID: 59u3s5jrQWCby7LY//suNg== X-IronPort-AV: E=McAfee;i="6700,10204,11288"; a="34992605" X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="34992605" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Dec 2024 00:22:37 -0800 X-CSE-ConnectionGUID: XdmDnQ0LQ7G6p8qxi4f+yw== X-CSE-MsgGUID: d/gupBKiQh2Ki8ui7xMhLA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,241,1728975600"; d="scan'208";a="98037694" Received: from black.fi.intel.com ([10.237.72.28]) by fmviesa009.fm.intel.com with ESMTP; 17 Dec 2024 00:22:26 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 5DA18949; Tue, 17 Dec 2024 10:22:23 +0200 (EET) From: Mika Westerberg To: linux-usb@vger.kernel.org Cc: Yehezkel Bernat , Michael Jamet , Lukas Wunner , Andreas Noever , Mika Westerberg Subject: [PATCH 12/12] thunderbolt: Handle DisplayPort tunnel activation asynchronously Date: Tue, 17 Dec 2024 10:22:22 +0200 Message-ID: <20241217082222.528602-13-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241217082222.528602-1-mika.westerberg@linux.intel.com> References: <20241217082222.528602-1-mika.westerberg@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sometimes setting up a DisplayPort tunnel may take quite long time. The reason is that the graphics driver (DPRX) is expected to issue read of certain monitor capabilities over the AUX channel and the "suggested" timeout from VESA is 5 seconds. If there is no graphics driver loaded this does not happen and currently we timeout and tear the tunnel down. The reason for this is that at least Intel discrete USB4 controllers do not send plug/unplug events about whether the DisplayPort cable from the GPU to the controller is connected or not, so in order to "release" the DisplayPort OUT adapter (the one that has monitor connected) we must tear the tunnel down after this timeout has been elapsed. In typical cases there is always graphics driver loaded, and also all the cables are connected but for instance in Intel graphics CI they only load the graphics driver after the system is fully booted up. This makes the driver to tear down the DisplayPort tunnel. To help this case we allow passing bigger or indefinite timeout through a new module parameter (dprx_timeout). To keep the driver bit more responsive during that time we change the way DisplayPort tunnels get activated. We first do the normal tunnel setup and then run the polling of DPRX capabilities read completion in a separate worker. This also makes the driver to accept bandwidth requests to already established DisplayPort tunnels more responsive. If the tunnel still fails to establish we will tear it down and remove the DisplayPort IN adapter from the dp_resource list to avoid using it again (unless we get hotplug to that adapter). Signed-off-by: Mika Westerberg --- drivers/thunderbolt/tb.c | 174 +++++++++++++----- drivers/thunderbolt/test.c | 90 ++++----- drivers/thunderbolt/tunnel.c | 341 +++++++++++++++++++++++------------ drivers/thunderbolt/tunnel.h | 47 ++++- 4 files changed, 444 insertions(+), 208 deletions(-) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 79ebf70f42e5..390abcfe7188 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -19,6 +19,12 @@ #define TB_TIMEOUT 100 /* ms */ #define TB_RELEASE_BW_TIMEOUT 10000 /* ms */ +/* + * How many time bandwidth allocation request from graphics driver is + * retried if the DP tunnel is still activating. + */ +#define TB_BW_ALLOC_RETRIES 3 + /* * Minimum bandwidth (in Mb/s) that is needed in the single transmitter/receiver * direction. This is 40G - 10% guard band bandwidth. @@ -69,15 +75,20 @@ static inline struct tb *tcm_to_tb(struct tb_cm *tcm) } struct tb_hotplug_event { - struct work_struct work; + struct delayed_work work; struct tb *tb; u64 route; u8 port; bool unplug; + int retry; }; static void tb_scan_port(struct tb_port *port); static void tb_handle_hotplug(struct work_struct *work); +static void tb_dp_resource_unavailable(struct tb *tb, struct tb_port *port, + const char *reason); +static void tb_queue_dp_bandwidth_request(struct tb *tb, u64 route, u8 port, + int retry, unsigned long delay); static void tb_queue_hotplug(struct tb *tb, u64 route, u8 port, bool unplug) { @@ -91,8 +102,8 @@ static void tb_queue_hotplug(struct tb *tb, u64 route, u8 port, bool unplug) ev->route = route; ev->port = port; ev->unplug = unplug; - INIT_WORK(&ev->work, tb_handle_hotplug); - queue_work(tb->wq, &ev->work); + INIT_DELAYED_WORK(&ev->work, tb_handle_hotplug); + queue_delayed_work(tb->wq, &ev->work, 0); } /* enumeration & hot plug handling */ @@ -962,7 +973,7 @@ static int tb_tunnel_usb3(struct tb *tb, struct tb_switch *sw) return 0; err_free: - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); err_reclaim: if (tb_route(parent)) tb_reclaim_usb3_bandwidth(tb, down, up); @@ -1726,7 +1737,7 @@ static void tb_deactivate_and_free_tunnel(struct tb_tunnel *tunnel) break; } - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } /* @@ -1863,12 +1874,76 @@ static struct tb_port *tb_find_dp_out(struct tb *tb, struct tb_port *in) return NULL; } +static void tb_dp_tunnel_active(struct tb_tunnel *tunnel, void *data) +{ + struct tb_port *in = tunnel->src_port; + struct tb_port *out = tunnel->dst_port; + struct tb *tb = data; + + mutex_lock(&tb->lock); + if (tb_tunnel_is_active(tunnel)) { + int consumed_up, consumed_down, ret; + + tb_tunnel_dbg(tunnel, "DPRX capabilities read completed\n"); + + /* If fail reading tunnel's consumed bandwidth, tear it down */ + ret = tb_tunnel_consumed_bandwidth(tunnel, &consumed_up, + &consumed_down); + if (ret) { + tb_tunnel_warn(tunnel, + "failed to read consumed bandwidth, tearing down\n"); + tb_deactivate_and_free_tunnel(tunnel); + } else { + tb_reclaim_usb3_bandwidth(tb, in, out); + /* + * Transition the links to asymmetric if the + * consumption exceeds the threshold. + */ + tb_configure_asym(tb, in, out, consumed_up, + consumed_down); + /* + * Update the domain with the new bandwidth + * estimation. + */ + tb_recalc_estimated_bandwidth(tb); + /* + * In case of DP tunnel exists, change host + * router's 1st children TMU mode to HiFi for + * CL0s to work. + */ + tb_increase_tmu_accuracy(tunnel); + } + } else { + struct tb_port *in = tunnel->src_port; + + /* + * This tunnel failed to establish. This means DPRX + * negotiation most likely did not complete which + * happens either because there is no graphics driver + * loaded or not all DP cables where connected to the + * discrete router. + * + * In both cases we remove the DP IN adapter from the + * available resources as it is not usable. This will + * also tear down the tunnel and try to re-use the + * released DP OUT. + * + * It will be added back only if there is hotplug for + * the DP IN again. + */ + tb_tunnel_warn(tunnel, "not active, tearing down\n"); + tb_dp_resource_unavailable(tb, in, "DPRX negotiation failed"); + } + mutex_unlock(&tb->lock); + + tb_domain_put(tb); +} + static void tb_tunnel_one_dp(struct tb *tb, struct tb_port *in, struct tb_port *out) { int available_up, available_down, ret, link_nr; struct tb_cm *tcm = tb_priv(tb); - int consumed_up, consumed_down; struct tb_tunnel *tunnel; /* @@ -1920,47 +1995,29 @@ static void tb_tunnel_one_dp(struct tb *tb, struct tb_port *in, available_up, available_down); tunnel = tb_tunnel_alloc_dp(tb, in, out, link_nr, available_up, - available_down); + available_down, tb_dp_tunnel_active, + tb_domain_get(tb)); if (!tunnel) { tb_port_dbg(out, "could not allocate DP tunnel\n"); goto err_reclaim_usb; } - if (tb_tunnel_activate(tunnel)) { + list_add_tail(&tunnel->list, &tcm->tunnel_list); + + ret = tb_tunnel_activate(tunnel); + if (ret && ret != -EINPROGRESS) { tb_port_info(out, "DP tunnel activation failed, aborting\n"); + list_del(&tunnel->list); goto err_free; } - /* If fail reading tunnel's consumed bandwidth, tear it down */ - ret = tb_tunnel_consumed_bandwidth(tunnel, &consumed_up, &consumed_down); - if (ret) - goto err_deactivate; - - list_add_tail(&tunnel->list, &tcm->tunnel_list); - - tb_reclaim_usb3_bandwidth(tb, in, out); - /* - * Transition the links to asymmetric if the consumption exceeds - * the threshold. - */ - tb_configure_asym(tb, in, out, consumed_up, consumed_down); - - /* Update the domain with the new bandwidth estimation */ - tb_recalc_estimated_bandwidth(tb); - - /* - * In case of DP tunnel exists, change host router's 1st children - * TMU mode to HiFi for CL0s to work. - */ - tb_increase_tmu_accuracy(tunnel); return; -err_deactivate: - tb_tunnel_deactivate(tunnel); err_free: - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); err_reclaim_usb: tb_reclaim_usb3_bandwidth(tb, in, out); + tb_domain_put(tb); err_detach_group: tb_detach_bandwidth_group(in); err_dealloc_dp: @@ -2180,7 +2237,7 @@ static int tb_disconnect_pci(struct tb *tb, struct tb_switch *sw) tb_tunnel_deactivate(tunnel); list_del(&tunnel->list); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); return 0; } @@ -2210,7 +2267,7 @@ static int tb_tunnel_pci(struct tb *tb, struct tb_switch *sw) if (tb_tunnel_activate(tunnel)) { tb_port_info(up, "PCIe tunnel activation failed, aborting\n"); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); return -EIO; } @@ -2269,7 +2326,7 @@ static int tb_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd, return 0; err_free: - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); err_clx: tb_enable_clx(sw); mutex_unlock(&tb->lock); @@ -2332,7 +2389,7 @@ static int tb_disconnect_xdomain_paths(struct tb *tb, struct tb_xdomain *xd, */ static void tb_handle_hotplug(struct work_struct *work) { - struct tb_hotplug_event *ev = container_of(work, typeof(*ev), work); + struct tb_hotplug_event *ev = container_of(work, typeof(*ev), work.work); struct tb *tb = ev->tb; struct tb_cm *tcm = tb_priv(tb); struct tb_switch *sw; @@ -2637,7 +2694,7 @@ static int tb_alloc_dp_bandwidth(struct tb_tunnel *tunnel, int *requested_up, static void tb_handle_dp_bandwidth_request(struct work_struct *work) { - struct tb_hotplug_event *ev = container_of(work, typeof(*ev), work); + struct tb_hotplug_event *ev = container_of(work, typeof(*ev), work.work); int requested_bw, requested_up, requested_down, ret; struct tb_tunnel *tunnel; struct tb *tb = ev->tb; @@ -2664,7 +2721,7 @@ static void tb_handle_dp_bandwidth_request(struct work_struct *work) goto put_sw; } - tb_port_dbg(in, "handling bandwidth allocation request\n"); + tb_port_dbg(in, "handling bandwidth allocation request, retry %d\n", ev->retry); tunnel = tb_find_tunnel(tb, TB_TUNNEL_DP, in, NULL); if (!tunnel) { @@ -2717,12 +2774,33 @@ static void tb_handle_dp_bandwidth_request(struct work_struct *work) ret = tb_alloc_dp_bandwidth(tunnel, &requested_up, &requested_down); if (ret) { - if (ret == -ENOBUFS) + if (ret == -ENOBUFS) { tb_tunnel_warn(tunnel, "not enough bandwidth available\n"); - else + } else if (ret == -ENOTCONN) { + tb_tunnel_dbg(tunnel, "not active yet\n"); + /* + * We got bandwidth allocation request but the + * tunnel is not yet active. This means that + * tb_dp_tunnel_active() is not yet called for + * this tunnel. Allow it some time and retry + * this request a couple of times. + */ + if (ev->retry < TB_BW_ALLOC_RETRIES) { + tb_tunnel_dbg(tunnel, + "retrying bandwidth allocation request\n"); + tb_queue_dp_bandwidth_request(tb, ev->route, + ev->port, + ev->retry + 1, + msecs_to_jiffies(50)); + } else { + tb_tunnel_dbg(tunnel, + "run out of retries, failing the request"); + } + } else { tb_tunnel_warn(tunnel, "failed to change bandwidth allocation\n"); + } } else { tb_tunnel_dbg(tunnel, "bandwidth allocation changed to %d/%d Mb/s\n", @@ -2743,7 +2821,8 @@ static void tb_handle_dp_bandwidth_request(struct work_struct *work) kfree(ev); } -static void tb_queue_dp_bandwidth_request(struct tb *tb, u64 route, u8 port) +static void tb_queue_dp_bandwidth_request(struct tb *tb, u64 route, u8 port, + int retry, unsigned long delay) { struct tb_hotplug_event *ev; @@ -2754,8 +2833,9 @@ static void tb_queue_dp_bandwidth_request(struct tb *tb, u64 route, u8 port) ev->tb = tb; ev->route = route; ev->port = port; - INIT_WORK(&ev->work, tb_handle_dp_bandwidth_request); - queue_work(tb->wq, &ev->work); + ev->retry = retry; + INIT_DELAYED_WORK(&ev->work, tb_handle_dp_bandwidth_request); + queue_delayed_work(tb->wq, &ev->work, delay); } static void tb_handle_notification(struct tb *tb, u64 route, @@ -2775,7 +2855,7 @@ static void tb_handle_notification(struct tb *tb, u64 route, if (tb_cfg_ack_notification(tb->ctl, route, error)) tb_warn(tb, "could not ack notification on %llx\n", route); - tb_queue_dp_bandwidth_request(tb, route, error->port); + tb_queue_dp_bandwidth_request(tb, route, error->port, 0, 0); break; default: @@ -2830,7 +2910,7 @@ static void tb_stop(struct tb *tb) */ if (tb_tunnel_is_dma(tunnel)) tb_tunnel_deactivate(tunnel); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } tb_switch_remove(tb->root_switch); tcm->hotplug_active = false; /* signal tb_handle_hotplug to quit */ @@ -3026,7 +3106,7 @@ static int tb_resume_noirq(struct tb *tb) if (tb_tunnel_is_usb3(tunnel)) usb3_delay = 500; tb_tunnel_deactivate(tunnel); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } /* Re-create our tunnels now */ diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c index 9475c6698c7d..1f4318249c22 100644 --- a/drivers/thunderbolt/test.c +++ b/drivers/thunderbolt/test.c @@ -1382,8 +1382,8 @@ static void tb_test_tunnel_pcie(struct kunit *test) KUNIT_EXPECT_PTR_EQ(test, tunnel2->paths[1]->hops[0].in_port, up); KUNIT_EXPECT_PTR_EQ(test, tunnel2->paths[1]->hops[1].out_port, down); - tb_tunnel_free(tunnel2); - tb_tunnel_free(tunnel1); + tb_tunnel_put(tunnel2); + tb_tunnel_put(tunnel1); } static void tb_test_tunnel_dp(struct kunit *test) @@ -1406,7 +1406,7 @@ static void tb_test_tunnel_dp(struct kunit *test) in = &host->ports[5]; out = &dev->ports[13]; - tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); + tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0, NULL, NULL); KUNIT_ASSERT_NOT_NULL(test, tunnel); KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, in); @@ -1421,7 +1421,7 @@ static void tb_test_tunnel_dp(struct kunit *test) KUNIT_ASSERT_EQ(test, tunnel->paths[2]->path_length, 2); KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[0].in_port, out); KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[1].out_port, in); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_tunnel_dp_chain(struct kunit *test) @@ -1452,7 +1452,7 @@ static void tb_test_tunnel_dp_chain(struct kunit *test) in = &host->ports[5]; out = &dev4->ports[14]; - tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); + tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0, NULL, NULL); KUNIT_ASSERT_NOT_NULL(test, tunnel); KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, in); @@ -1467,7 +1467,7 @@ static void tb_test_tunnel_dp_chain(struct kunit *test) KUNIT_ASSERT_EQ(test, tunnel->paths[2]->path_length, 3); KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[0].in_port, out); KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[2].out_port, in); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_tunnel_dp_tree(struct kunit *test) @@ -1502,7 +1502,7 @@ static void tb_test_tunnel_dp_tree(struct kunit *test) in = &dev2->ports[13]; out = &dev5->ports[13]; - tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); + tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0, NULL, NULL); KUNIT_ASSERT_NOT_NULL(test, tunnel); KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, in); @@ -1517,7 +1517,7 @@ static void tb_test_tunnel_dp_tree(struct kunit *test) KUNIT_ASSERT_EQ(test, tunnel->paths[2]->path_length, 4); KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[0].in_port, out); KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[3].out_port, in); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_tunnel_dp_max_length(struct kunit *test) @@ -1567,7 +1567,7 @@ static void tb_test_tunnel_dp_max_length(struct kunit *test) in = &dev6->ports[13]; out = &dev12->ports[13]; - tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); + tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0, NULL, NULL); KUNIT_ASSERT_NOT_NULL(test, tunnel); KUNIT_EXPECT_EQ(test, tunnel->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel->src_port, in); @@ -1597,7 +1597,7 @@ static void tb_test_tunnel_dp_max_length(struct kunit *test) KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[6].out_port, &host->ports[1]); KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[2]->hops[12].out_port, in); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_tunnel_3dp(struct kunit *test) @@ -1637,7 +1637,7 @@ static void tb_test_tunnel_3dp(struct kunit *test) out2 = &dev5->ports[13]; out3 = &dev4->ports[14]; - tunnel1 = tb_tunnel_alloc_dp(NULL, in1, out1, 1, 0, 0); + tunnel1 = tb_tunnel_alloc_dp(NULL, in1, out1, 1, 0, 0, NULL, NULL); KUNIT_ASSERT_TRUE(test, tunnel1 != NULL); KUNIT_EXPECT_EQ(test, tunnel1->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel1->src_port, in1); @@ -1645,7 +1645,7 @@ static void tb_test_tunnel_3dp(struct kunit *test) KUNIT_ASSERT_EQ(test, tunnel1->npaths, 3); KUNIT_ASSERT_EQ(test, tunnel1->paths[0]->path_length, 3); - tunnel2 = tb_tunnel_alloc_dp(NULL, in2, out2, 1, 0, 0); + tunnel2 = tb_tunnel_alloc_dp(NULL, in2, out2, 1, 0, 0, NULL, NULL); KUNIT_ASSERT_TRUE(test, tunnel2 != NULL); KUNIT_EXPECT_EQ(test, tunnel2->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel2->src_port, in2); @@ -1653,7 +1653,7 @@ static void tb_test_tunnel_3dp(struct kunit *test) KUNIT_ASSERT_EQ(test, tunnel2->npaths, 3); KUNIT_ASSERT_EQ(test, tunnel2->paths[0]->path_length, 4); - tunnel3 = tb_tunnel_alloc_dp(NULL, in3, out3, 1, 0, 0); + tunnel3 = tb_tunnel_alloc_dp(NULL, in3, out3, 1, 0, 0, NULL, NULL); KUNIT_ASSERT_TRUE(test, tunnel3 != NULL); KUNIT_EXPECT_EQ(test, tunnel3->type, TB_TUNNEL_DP); KUNIT_EXPECT_PTR_EQ(test, tunnel3->src_port, in3); @@ -1661,8 +1661,8 @@ static void tb_test_tunnel_3dp(struct kunit *test) KUNIT_ASSERT_EQ(test, tunnel3->npaths, 3); KUNIT_ASSERT_EQ(test, tunnel3->paths[0]->path_length, 3); - tb_tunnel_free(tunnel2); - tb_tunnel_free(tunnel1); + tb_tunnel_put(tunnel2); + tb_tunnel_put(tunnel1); } static void tb_test_tunnel_usb3(struct kunit *test) @@ -1716,8 +1716,8 @@ static void tb_test_tunnel_usb3(struct kunit *test) KUNIT_EXPECT_PTR_EQ(test, tunnel2->paths[1]->hops[0].in_port, up); KUNIT_EXPECT_PTR_EQ(test, tunnel2->paths[1]->hops[1].out_port, down); - tb_tunnel_free(tunnel2); - tb_tunnel_free(tunnel1); + tb_tunnel_put(tunnel2); + tb_tunnel_put(tunnel1); } static void tb_test_tunnel_port_on_path(struct kunit *test) @@ -1750,7 +1750,7 @@ static void tb_test_tunnel_port_on_path(struct kunit *test) in = &dev2->ports[13]; out = &dev5->ports[13]; - dp_tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); + dp_tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0, NULL, NULL); KUNIT_ASSERT_NOT_NULL(test, dp_tunnel); KUNIT_EXPECT_TRUE(test, tb_tunnel_port_on_path(dp_tunnel, in)); @@ -1783,7 +1783,7 @@ static void tb_test_tunnel_port_on_path(struct kunit *test) port = &dev4->ports[1]; KUNIT_EXPECT_FALSE(test, tb_tunnel_port_on_path(dp_tunnel, port)); - tb_tunnel_free(dp_tunnel); + tb_tunnel_put(dp_tunnel); } static void tb_test_tunnel_dma(struct kunit *test) @@ -1826,7 +1826,7 @@ static void tb_test_tunnel_dma(struct kunit *test) KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[0].out_port, port); KUNIT_EXPECT_EQ(test, tunnel->paths[1]->hops[0].next_hop_index, 8); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_tunnel_dma_rx(struct kunit *test) @@ -1863,7 +1863,7 @@ static void tb_test_tunnel_dma_rx(struct kunit *test) KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].out_port, nhi); KUNIT_EXPECT_EQ(test, tunnel->paths[0]->hops[0].next_hop_index, 2); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_tunnel_dma_tx(struct kunit *test) @@ -1900,7 +1900,7 @@ static void tb_test_tunnel_dma_tx(struct kunit *test) KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[0]->hops[0].out_port, port); KUNIT_EXPECT_EQ(test, tunnel->paths[0]->hops[0].next_hop_index, 15); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_tunnel_dma_chain(struct kunit *test) @@ -1966,7 +1966,7 @@ static void tb_test_tunnel_dma_chain(struct kunit *test) KUNIT_EXPECT_PTR_EQ(test, tunnel->paths[1]->hops[2].out_port, port); KUNIT_EXPECT_EQ(test, tunnel->paths[1]->hops[2].next_hop_index, 8); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_tunnel_dma_match(struct kunit *test) @@ -1993,7 +1993,7 @@ static void tb_test_tunnel_dma_match(struct kunit *test) KUNIT_ASSERT_TRUE(test, tb_tunnel_match_dma(tunnel, -1, -1, -1, -1)); KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, 8, -1, 8, -1)); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); tunnel = tb_tunnel_alloc_dma(NULL, nhi, port, 15, 1, -1, -1); KUNIT_ASSERT_NOT_NULL(test, tunnel); @@ -2005,7 +2005,7 @@ static void tb_test_tunnel_dma_match(struct kunit *test) KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, -1, -1, 15, 1)); KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, 15, 11, -1, -1)); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); tunnel = tb_tunnel_alloc_dma(NULL, nhi, port, -1, -1, 15, 11); KUNIT_ASSERT_NOT_NULL(test, tunnel); @@ -2017,7 +2017,7 @@ static void tb_test_tunnel_dma_match(struct kunit *test) KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, -1, -1, 10, 11)); KUNIT_ASSERT_FALSE(test, tb_tunnel_match_dma(tunnel, 15, 11, -1, -1)); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_credit_alloc_legacy_not_bonded(struct kunit *test) @@ -2050,7 +2050,7 @@ static void tb_test_credit_alloc_legacy_not_bonded(struct kunit *test) KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U); KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 16U); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_credit_alloc_legacy_bonded(struct kunit *test) @@ -2083,7 +2083,7 @@ static void tb_test_credit_alloc_legacy_bonded(struct kunit *test) KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U); KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 32U); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_credit_alloc_pcie(struct kunit *test) @@ -2116,7 +2116,7 @@ static void tb_test_credit_alloc_pcie(struct kunit *test) KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U); KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 64U); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_credit_alloc_without_dp(struct kunit *test) @@ -2166,7 +2166,7 @@ static void tb_test_credit_alloc_without_dp(struct kunit *test) KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U); KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 64U); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_credit_alloc_dp(struct kunit *test) @@ -2182,7 +2182,7 @@ static void tb_test_credit_alloc_dp(struct kunit *test) in = &host->ports[5]; out = &dev->ports[14]; - tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); + tunnel = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0, NULL, NULL); KUNIT_ASSERT_NOT_NULL(test, tunnel); KUNIT_ASSERT_EQ(test, tunnel->npaths, (size_t)3); @@ -2210,7 +2210,7 @@ static void tb_test_credit_alloc_dp(struct kunit *test) KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U); KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 1U); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_credit_alloc_usb3(struct kunit *test) @@ -2243,7 +2243,7 @@ static void tb_test_credit_alloc_usb3(struct kunit *test) KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U); KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 32U); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_credit_alloc_dma(struct kunit *test) @@ -2279,7 +2279,7 @@ static void tb_test_credit_alloc_dma(struct kunit *test) KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U); KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U); - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); } static void tb_test_credit_alloc_dma_multiple(struct kunit *test) @@ -2356,7 +2356,7 @@ static void tb_test_credit_alloc_dma_multiple(struct kunit *test) * Release the first DMA tunnel. That should make 14 buffers * available for the next tunnel. */ - tb_tunnel_free(tunnel1); + tb_tunnel_put(tunnel1); tunnel3 = tb_tunnel_alloc_dma(NULL, nhi, port, 10, 3, 10, 3); KUNIT_ASSERT_NOT_NULL(test, tunnel3); @@ -2375,8 +2375,8 @@ static void tb_test_credit_alloc_dma_multiple(struct kunit *test) KUNIT_EXPECT_EQ(test, path->hops[1].nfc_credits, 0U); KUNIT_EXPECT_EQ(test, path->hops[1].initial_credits, 14U); - tb_tunnel_free(tunnel3); - tb_tunnel_free(tunnel2); + tb_tunnel_put(tunnel3); + tb_tunnel_put(tunnel2); } static struct tb_tunnel *TB_TEST_PCIE_TUNNEL(struct kunit *test, @@ -2418,7 +2418,7 @@ static struct tb_tunnel *TB_TEST_DP_TUNNEL1(struct kunit *test, in = &host->ports[5]; out = &dev->ports[13]; - dp_tunnel1 = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); + dp_tunnel1 = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0, NULL, NULL); KUNIT_ASSERT_NOT_NULL(test, dp_tunnel1); KUNIT_ASSERT_EQ(test, dp_tunnel1->npaths, (size_t)3); @@ -2455,7 +2455,7 @@ static struct tb_tunnel *TB_TEST_DP_TUNNEL2(struct kunit *test, in = &host->ports[6]; out = &dev->ports[14]; - dp_tunnel2 = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0); + dp_tunnel2 = tb_tunnel_alloc_dp(NULL, in, out, 1, 0, 0, NULL, NULL); KUNIT_ASSERT_NOT_NULL(test, dp_tunnel2); KUNIT_ASSERT_EQ(test, dp_tunnel2->npaths, (size_t)3); @@ -2595,12 +2595,12 @@ static void tb_test_credit_alloc_all(struct kunit *test) dma_tunnel1 = TB_TEST_DMA_TUNNEL1(test, host, dev); dma_tunnel2 = TB_TEST_DMA_TUNNEL2(test, host, dev); - tb_tunnel_free(dma_tunnel2); - tb_tunnel_free(dma_tunnel1); - tb_tunnel_free(usb3_tunnel); - tb_tunnel_free(dp_tunnel2); - tb_tunnel_free(dp_tunnel1); - tb_tunnel_free(pcie_tunnel); + tb_tunnel_put(dma_tunnel2); + tb_tunnel_put(dma_tunnel1); + tb_tunnel_put(usb3_tunnel); + tb_tunnel_put(dp_tunnel2); + tb_tunnel_put(dp_tunnel1); + tb_tunnel_put(pcie_tunnel); } static const u32 root_directory[] = { diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index c625b5b84a7c..8229a6fbda5a 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -70,6 +70,24 @@ #define USB4_V2_PCI_MIN_BANDWIDTH (1500 * TB_PCI_WEIGHT) #define USB4_V2_USB3_MIN_BANDWIDTH (1500 * TB_USB3_WEIGHT) +/* + * According to VESA spec, the DPRX negotiation shall compete in 5 + * seconds after tunnel is established. Since at least i915 can runtime + * suspend if there is nothing connected, and that it polls any new + * connections every 10 seconds, we use 12 seconds here. + * + * These are in ms. + */ +#define TB_DPRX_TIMEOUT 12000 +#define TB_DPRX_WAIT_TIMEOUT 25 +#define TB_DPRX_POLL_DELAY 50 + +static int dprx_timeout = TB_DPRX_TIMEOUT; +module_param(dprx_timeout, int, 0444); +MODULE_PARM_DESC(dprx_timeout, + "DPRX capability read timeout in ms, -1 waits forever (default: " + __MODULE_STRING(TB_DPRX_TIMEOUT) ")"); + static unsigned int dma_credits = TB_DMA_CREDITS; module_param(dma_credits, uint, 0444); MODULE_PARM_DESC(dma_credits, "specify custom credits for DMA tunnels (default: " @@ -82,6 +100,9 @@ MODULE_PARM_DESC(bw_alloc_mode, static const char * const tb_tunnel_names[] = { "PCI", "DP", "DMA", "USB3" }; +/* Synchronizes kref_get()/put() of struct tb_tunnel */ +static DEFINE_MUTEX(tb_tunnel_lock); + static inline unsigned int tb_usable_credits(const struct tb_port *port) { return port->total_credits - port->ctl_credits; @@ -155,7 +176,7 @@ static struct tb_tunnel *tb_tunnel_alloc(struct tb *tb, size_t npaths, tunnel->paths = kcalloc(npaths, sizeof(tunnel->paths[0]), GFP_KERNEL); if (!tunnel->paths) { - tb_tunnel_free(tunnel); + kfree(tunnel); return NULL; } @@ -163,10 +184,42 @@ static struct tb_tunnel *tb_tunnel_alloc(struct tb *tb, size_t npaths, tunnel->tb = tb; tunnel->npaths = npaths; tunnel->type = type; + kref_init(&tunnel->kref); return tunnel; } +static void tb_tunnel_get(struct tb_tunnel *tunnel) +{ + mutex_lock(&tb_tunnel_lock); + kref_get(&tunnel->kref); + mutex_unlock(&tb_tunnel_lock); +} + +static void tb_tunnel_destroy(struct kref *kref) +{ + struct tb_tunnel *tunnel = container_of(kref, typeof(*tunnel), kref); + int i; + + if (tunnel->destroy) + tunnel->destroy(tunnel); + + for (i = 0; i < tunnel->npaths; i++) { + if (tunnel->paths[i]) + tb_path_free(tunnel->paths[i]); + } + + kfree(tunnel->paths); + kfree(tunnel); +} + +void tb_tunnel_put(struct tb_tunnel *tunnel) +{ + mutex_lock(&tb_tunnel_lock); + kref_put(&tunnel->kref, tb_tunnel_destroy); + mutex_unlock(&tb_tunnel_lock); +} + static int tb_pci_set_ext_encapsulation(struct tb_tunnel *tunnel, bool enable) { struct tb_port *port = tb_upstream_port(tunnel->dst_port->sw); @@ -355,7 +408,7 @@ struct tb_tunnel *tb_tunnel_discover_pci(struct tb *tb, struct tb_port *down, err_deactivate: tb_tunnel_deactivate(tunnel); err_free: - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); return NULL; } @@ -404,7 +457,7 @@ struct tb_tunnel *tb_tunnel_alloc_pci(struct tb *tb, struct tb_port *up, return tunnel; err_free: - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); return NULL; } @@ -889,6 +942,90 @@ static void tb_dp_post_deactivate(struct tb_tunnel *tunnel) } } +static ktime_t dprx_timeout_to_ktime(int timeout_msec) +{ + return timeout_msec >= 0 ? + ktime_add_ms(ktime_get(), timeout_msec) : KTIME_MAX; +} + +static int tb_dp_wait_dprx(struct tb_tunnel *tunnel, int timeout_msec) +{ + ktime_t timeout = dprx_timeout_to_ktime(timeout_msec); + struct tb_port *in = tunnel->src_port; + + /* + * Wait for DPRX done. Normally it should be already set for + * active tunnel. + */ + do { + u32 val; + int ret; + + ret = tb_port_read(in, &val, TB_CFG_PORT, + in->cap_adap + DP_COMMON_CAP, 1); + if (ret) + return ret; + + if (val & DP_COMMON_CAP_DPRX_DONE) + return 0; + + usleep_range(100, 150); + } while (ktime_before(ktime_get(), timeout)); + + tb_tunnel_dbg(tunnel, "DPRX read timeout\n"); + return -ETIMEDOUT; +} + +static void tb_dp_dprx_work(struct work_struct *work) +{ + struct tb_tunnel *tunnel = container_of(work, typeof(*tunnel), dprx_work.work); + struct tb *tb = tunnel->tb; + + if (!tunnel->dprx_canceled) { + mutex_lock(&tb->lock); + if (tb_dp_is_usb4(tunnel->src_port->sw) && + tb_dp_wait_dprx(tunnel, TB_DPRX_WAIT_TIMEOUT)) { + if (ktime_before(ktime_get(), tunnel->dprx_timeout)) { + queue_delayed_work(tb->wq, &tunnel->dprx_work, + msecs_to_jiffies(TB_DPRX_POLL_DELAY)); + mutex_unlock(&tb->lock); + return; + } + } else { + tunnel->state = TB_TUNNEL_ACTIVE; + } + mutex_unlock(&tb->lock); + } + + if (tunnel->callback) + tunnel->callback(tunnel, tunnel->callback_data); +} + +static int tb_dp_dprx_start(struct tb_tunnel *tunnel) +{ + /* + * Bump up the reference to keep the tunnel around. It will be + * dropped in tb_dp_dprx_stop() once the tunnel is deactivated. + */ + tb_tunnel_get(tunnel); + + if (tunnel->callback) { + tunnel->dprx_timeout = dprx_timeout_to_ktime(dprx_timeout); + queue_delayed_work(tunnel->tb->wq, &tunnel->dprx_work, 0); + return -EINPROGRESS; + } + + return tb_dp_is_usb4(tunnel->src_port->sw) ? + tb_dp_wait_dprx(tunnel, dprx_timeout) : 0; +} + +static void tb_dp_dprx_stop(struct tb_tunnel *tunnel) +{ + tunnel->dprx_canceled = true; + cancel_delayed_work(&tunnel->dprx_work); + tb_tunnel_put(tunnel); +} + static int tb_dp_activate(struct tb_tunnel *tunnel, bool active) { int ret; @@ -910,6 +1047,7 @@ static int tb_dp_activate(struct tb_tunnel *tunnel, bool active) paths[TB_DP_AUX_PATH_IN]->hops[0].in_hop_index, paths[TB_DP_AUX_PATH_OUT]->hops[last].next_hop_index); } else { + tb_dp_dprx_stop(tunnel); tb_dp_port_hpd_clear(tunnel->src_port); tb_dp_port_set_hops(tunnel->src_port, 0, 0, 0); if (tb_port_is_dpout(tunnel->dst_port)) @@ -920,10 +1058,13 @@ static int tb_dp_activate(struct tb_tunnel *tunnel, bool active) if (ret) return ret; - if (tb_port_is_dpout(tunnel->dst_port)) - return tb_dp_port_enable(tunnel->dst_port, active); + if (tb_port_is_dpout(tunnel->dst_port)) { + ret = tb_dp_port_enable(tunnel->dst_port, active); + if (ret) + return ret; + } - return 0; + return active ? tb_dp_dprx_start(tunnel) : 0; } /** @@ -1076,35 +1217,6 @@ static int tb_dp_alloc_bandwidth(struct tb_tunnel *tunnel, int *alloc_up, return 0; } -static int tb_dp_wait_dprx(struct tb_tunnel *tunnel, int timeout_msec) -{ - ktime_t timeout = ktime_add_ms(ktime_get(), timeout_msec); - struct tb_port *in = tunnel->src_port; - - /* - * Wait for DPRX done. Normally it should be already set for - * active tunnel. - */ - do { - u32 val; - int ret; - - ret = tb_port_read(in, &val, TB_CFG_PORT, - in->cap_adap + DP_COMMON_CAP, 1); - if (ret) - return ret; - - if (val & DP_COMMON_CAP_DPRX_DONE) { - tb_tunnel_dbg(tunnel, "DPRX read done\n"); - return 0; - } - usleep_range(100, 150); - } while (ktime_before(ktime_get(), timeout)); - - tb_tunnel_dbg(tunnel, "DPRX read timeout\n"); - return -ETIMEDOUT; -} - /* Read cap from tunnel DP IN */ static int tb_dp_read_cap(struct tb_tunnel *tunnel, unsigned int cap, u32 *rate, u32 *lanes) @@ -1168,35 +1280,39 @@ static int tb_dp_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, int ret; if (tb_dp_is_usb4(sw)) { - /* - * On USB4 routers check if the bandwidth allocation - * mode is enabled first and then read the bandwidth - * through those registers. - */ - ret = tb_dp_bandwidth_mode_consumed_bandwidth(tunnel, consumed_up, - consumed_down); - if (ret < 0) { - if (ret != -EOPNOTSUPP) + ret = tb_dp_wait_dprx(tunnel, 0); + if (ret) { + if (ret == -ETIMEDOUT) { + /* + * While we wait for DPRX complete the + * tunnel consumes as much as it had + * been reserved initially. + */ + ret = tb_dp_read_cap(tunnel, DP_REMOTE_CAP, + &rate, &lanes); + if (ret) + return ret; + } else { + return ret; + } + } else { + /* + * On USB4 routers check if the bandwidth allocation + * mode is enabled first and then read the bandwidth + * through those registers. + */ + ret = tb_dp_bandwidth_mode_consumed_bandwidth(tunnel, consumed_up, + consumed_down); + if (ret < 0) { + if (ret != -EOPNOTSUPP) + return ret; + } else if (!ret) { + return 0; + } + ret = tb_dp_read_cap(tunnel, DP_COMMON_CAP, &rate, &lanes); + if (ret) return ret; - } else if (!ret) { - return 0; } - /* - * Then see if the DPRX negotiation is ready and if yes - * return that bandwidth (it may be smaller than the - * reduced one). According to VESA spec, the DPRX - * negotiation shall compete in 5 seconds after tunnel - * established. Since at least i915 can runtime suspend - * if there is nothing connected, and that it polls any - * new connections every 10 seconds, we use 12 seconds - * here. - */ - ret = tb_dp_wait_dprx(tunnel, 12000); - if (ret) - return ret; - ret = tb_dp_read_cap(tunnel, DP_COMMON_CAP, &rate, &lanes); - if (ret) - return ret; } else if (sw->generation >= 2) { ret = tb_dp_read_cap(tunnel, DP_REMOTE_CAP, &rate, &lanes); if (ret) @@ -1427,7 +1543,7 @@ struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in, err_deactivate: tb_tunnel_deactivate(tunnel); err_free: - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); return NULL; } @@ -1442,15 +1558,24 @@ struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in, * %0 if no available bandwidth. * @max_down: Maximum available downstream bandwidth for the DP tunnel. * %0 if no available bandwidth. + * @callback: Optional callback that is called when the DP tunnel is + * fully activated (or there is an error) + * @callback_data: Optional data for @callback * * Allocates a tunnel between @in and @out that is capable of tunneling - * Display Port traffic. + * Display Port traffic. If @callback is not %NULL it will be called + * after tb_tunnel_activate() once the tunnel has been fully activated. + * It can call tb_tunnel_is_active() to check if activation was + * successful (or if it returns %false there was some sort of issue). + * The @callback is called without @tb->lock held. * - * Return: Returns a tb_tunnel on success or NULL on failure. + * Return: Returns a tb_tunnel on success or &NULL on failure. */ struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, struct tb_port *out, int link_nr, - int max_up, int max_down) + int max_up, int max_down, + void (*callback)(struct tb_tunnel *, void *), + void *callback_data) { struct tb_tunnel *tunnel; struct tb_path **paths; @@ -1475,6 +1600,9 @@ struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, tunnel->dst_port = out; tunnel->max_up = max_up; tunnel->max_down = max_down; + tunnel->callback = callback; + tunnel->callback_data = callback_data; + INIT_DELAYED_WORK(&tunnel->dprx_work, tb_dp_dprx_work); paths = tunnel->paths; pm_support = usb4_switch_version(in->sw) >= 2; @@ -1503,7 +1631,7 @@ struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, return tunnel; err_free: - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); return NULL; } @@ -1715,7 +1843,7 @@ struct tb_tunnel *tb_tunnel_alloc_dma(struct tb *tb, struct tb_port *nhi, return tunnel; err_free: - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); return NULL; } @@ -2041,7 +2169,7 @@ struct tb_tunnel *tb_tunnel_discover_usb3(struct tb *tb, struct tb_port *down, err_deactivate: tb_tunnel_deactivate(tunnel); err_free: - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); return NULL; } @@ -2097,7 +2225,7 @@ struct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *tb, struct tb_port *up, path = tb_path_alloc(tb, down, TB_USB3_HOPID, up, TB_USB3_HOPID, 0, "USB3 Down"); if (!path) { - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); return NULL; } tb_usb3_init_path(path); @@ -2106,7 +2234,7 @@ struct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *tb, struct tb_port *up, path = tb_path_alloc(tb, up, TB_USB3_HOPID, down, TB_USB3_HOPID, 0, "USB3 Up"); if (!path) { - tb_tunnel_free(tunnel); + tb_tunnel_put(tunnel); return NULL; } tb_usb3_init_path(path); @@ -2127,31 +2255,6 @@ struct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *tb, struct tb_port *up, return tunnel; } -/** - * tb_tunnel_free() - free a tunnel - * @tunnel: Tunnel to be freed - * - * Frees a tunnel. The tunnel does not need to be deactivated. - */ -void tb_tunnel_free(struct tb_tunnel *tunnel) -{ - int i; - - if (!tunnel) - return; - - if (tunnel->destroy) - tunnel->destroy(tunnel); - - for (i = 0; i < tunnel->npaths; i++) { - if (tunnel->paths[i]) - tb_path_free(tunnel->paths[i]); - } - - kfree(tunnel->paths); - kfree(tunnel); -} - /** * tb_tunnel_is_invalid - check whether an activated path is still valid * @tunnel: Tunnel to check @@ -2173,7 +2276,10 @@ bool tb_tunnel_is_invalid(struct tb_tunnel *tunnel) * tb_tunnel_activate() - activate a tunnel * @tunnel: Tunnel to activate * - * Return: 0 on success and negative errno in case if failure + * Return: 0 on success and negative errno in case if failure. + * Specifically returns %-EINPROGRESS if the tunnel activation is still + * in progress (that's for DP tunnels to complete DPRX capabilities + * read). */ int tb_tunnel_activate(struct tb_tunnel *tunnel) { @@ -2192,6 +2298,8 @@ int tb_tunnel_activate(struct tb_tunnel *tunnel) } } + tunnel->state = TB_TUNNEL_ACTIVATING; + if (tunnel->pre_activate) { res = tunnel->pre_activate(tunnel); if (res) @@ -2206,10 +2314,14 @@ int tb_tunnel_activate(struct tb_tunnel *tunnel) if (tunnel->activate) { res = tunnel->activate(tunnel, true); - if (res) + if (res) { + if (res == -EINPROGRESS) + return res; goto err; + } } + tunnel->state = TB_TUNNEL_ACTIVE; return 0; err: @@ -2238,6 +2350,8 @@ void tb_tunnel_deactivate(struct tb_tunnel *tunnel) if (tunnel->post_deactivate) tunnel->post_deactivate(tunnel); + + tunnel->state = TB_TUNNEL_INACTIVE; } /** @@ -2264,18 +2378,10 @@ bool tb_tunnel_port_on_path(const struct tb_tunnel *tunnel, return false; } -static bool tb_tunnel_is_active(const struct tb_tunnel *tunnel) +// Is tb_tunnel_activate() called for the tunnel +static bool tb_tunnel_is_activated(const struct tb_tunnel *tunnel) { - int i; - - for (i = 0; i < tunnel->npaths; i++) { - if (!tunnel->paths[i]) - return false; - if (!tunnel->paths[i]->activated) - return false; - } - - return true; + return tunnel->state == TB_TUNNEL_ACTIVATING || tb_tunnel_is_active(tunnel); } /** @@ -2292,7 +2398,7 @@ int tb_tunnel_maximum_bandwidth(struct tb_tunnel *tunnel, int *max_up, int *max_down) { if (!tb_tunnel_is_active(tunnel)) - return -EINVAL; + return -ENOTCONN; if (tunnel->maximum_bandwidth) return tunnel->maximum_bandwidth(tunnel, max_up, max_down); @@ -2313,7 +2419,7 @@ int tb_tunnel_allocated_bandwidth(struct tb_tunnel *tunnel, int *allocated_up, int *allocated_down) { if (!tb_tunnel_is_active(tunnel)) - return -EINVAL; + return -ENOTCONN; if (tunnel->allocated_bandwidth) return tunnel->allocated_bandwidth(tunnel, allocated_up, @@ -2336,7 +2442,7 @@ int tb_tunnel_alloc_bandwidth(struct tb_tunnel *tunnel, int *alloc_up, int *alloc_down) { if (!tb_tunnel_is_active(tunnel)) - return -EINVAL; + return -ENOTCONN; if (tunnel->alloc_bandwidth) return tunnel->alloc_bandwidth(tunnel, alloc_up, alloc_down); @@ -2361,7 +2467,14 @@ int tb_tunnel_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, { int up_bw = 0, down_bw = 0; - if (tb_tunnel_is_active(tunnel) && tunnel->consumed_bandwidth) { + /* + * Here we need to distinguish between not active tunnel from + * tunnels that are either fully active or activation started. + * The latter is true for DP tunnels where we must report the + * consumed to be the maximum we gave it until DPRX capabilities + * read is done by the graphics driver. + */ + if (tb_tunnel_is_activated(tunnel) && tunnel->consumed_bandwidth) { int ret; ret = tunnel->consumed_bandwidth(tunnel, &up_bw, &down_bw); @@ -2390,7 +2503,7 @@ int tb_tunnel_consumed_bandwidth(struct tb_tunnel *tunnel, int *consumed_up, int tb_tunnel_release_unused_bandwidth(struct tb_tunnel *tunnel) { if (!tb_tunnel_is_active(tunnel)) - return 0; + return -ENOTCONN; if (tunnel->release_unused_bandwidth) { int ret; diff --git a/drivers/thunderbolt/tunnel.h b/drivers/thunderbolt/tunnel.h index 3d3ab180cb9b..7f6d3a18a41e 100644 --- a/drivers/thunderbolt/tunnel.h +++ b/drivers/thunderbolt/tunnel.h @@ -18,8 +18,21 @@ enum tb_tunnel_type { TB_TUNNEL_USB3, }; +/** + * enum tb_tunnel_state - State of a tunnel + * @TB_TUNNEL_INACTIVE: tb_tunnel_activate() is not called for the tunnel + * @TB_TUNNEL_ACTIVATING: tb_tunnel_activate() returned successfully for the tunnel + * @TB_TUNNEL_ACTIVE: The tunnel is fully active + */ +enum tb_tunnel_state { + TB_TUNNEL_INACTIVE, + TB_TUNNEL_ACTIVATING, + TB_TUNNEL_ACTIVE, +}; + /** * struct tb_tunnel - Tunnel between two ports + * @kref: Reference count * @tb: Pointer to the domain * @src_port: Source port of the tunnel * @dst_port: Destination port of the tunnel. For discovered incomplete @@ -41,6 +54,7 @@ enum tb_tunnel_type { * @reclaim_available_bandwidth: Reclaim back available bandwidth * @list: Tunnels are linked using this field * @type: Type of the tunnel + * @state: Current state of the tunnel * @max_up: Maximum upstream bandwidth (Mb/s) available for the tunnel. * Only set if the bandwidth needs to be limited. * @max_down: Maximum downstream bandwidth (Mb/s) available for the tunnel. @@ -49,8 +63,14 @@ enum tb_tunnel_type { * @allocated_down: Allocated downstream bandwidth (only for USB3) * @bw_mode: DP bandwidth allocation mode registers can be used to * determine consumed and allocated bandwidth + * @dprx_canceled: Was DPRX capabilities read poll canceled + * @dprx_timeout: If set DPRX capabilities read poll work will timeout after this passes + * @dprx_work: Worker that is scheduled to poll completion of DPRX capabilities read + * @callback: Optional callback called when DP tunnel is fully activated + * @callback_data: Optional data for @callback */ struct tb_tunnel { + struct kref kref; struct tb *tb; struct tb_port *src_port; struct tb_port *dst_port; @@ -74,11 +94,17 @@ struct tb_tunnel { int *available_down); struct list_head list; enum tb_tunnel_type type; + enum tb_tunnel_state state; int max_up; int max_down; int allocated_up; int allocated_down; bool bw_mode; + bool dprx_canceled; + ktime_t dprx_timeout; + struct delayed_work dprx_work; + void (*callback)(struct tb_tunnel *tunnel, void *data); + void *callback_data; }; struct tb_tunnel *tb_tunnel_discover_pci(struct tb *tb, struct tb_port *down, @@ -91,7 +117,9 @@ struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in, bool alloc_hopid); struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in, struct tb_port *out, int link_nr, - int max_up, int max_down); + int max_up, int max_down, + void (*callback)(struct tb_tunnel *, void *), + void *callback_data); struct tb_tunnel *tb_tunnel_alloc_dma(struct tb *tb, struct tb_port *nhi, struct tb_port *dst, int transmit_path, int transmit_ring, int receive_path, @@ -104,9 +132,24 @@ struct tb_tunnel *tb_tunnel_alloc_usb3(struct tb *tb, struct tb_port *up, struct tb_port *down, int max_up, int max_down); -void tb_tunnel_free(struct tb_tunnel *tunnel); +void tb_tunnel_put(struct tb_tunnel *tunnel); int tb_tunnel_activate(struct tb_tunnel *tunnel); void tb_tunnel_deactivate(struct tb_tunnel *tunnel); + +/** + * tb_tunnel_is_active() - Is tunnel fully activated + * @tunnel: Tunnel to check + * + * Returns %true if @tunnel is fully activated. For other than DP + * tunnels this is pretty much once tb_tunnel_activate() returns + * successfully. However, for DP tunnels this returns %true only once the + * DPRX capabilities read has been issued successfully. + */ +static inline bool tb_tunnel_is_active(const struct tb_tunnel *tunnel) +{ + return tunnel->state == TB_TUNNEL_ACTIVE; +} + bool tb_tunnel_is_invalid(struct tb_tunnel *tunnel); bool tb_tunnel_port_on_path(const struct tb_tunnel *tunnel, const struct tb_port *port);