From nobody Fri Jun 12 20:20:17 2026 Received: from mail-lj1-f172.google.com (mail-lj1-f172.google.com [209.85.208.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D49E93932C9 for ; Tue, 12 May 2026 21:47:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778622439; cv=none; b=BMl9m3wK8yt0v76/2bYh46/jildv/0ldDafYs9fxwvxutpgCLiaUK/ViydMIoeY8YzP0HtIGpmiPTgpf+m13OH2ufW2qJ1paL7S0pdE1DOuSUBcsyeRQPcaUQDf9bblm94ycbzZlfEOYBMr5iDmXr0JbLpvphdqU1OvPmvU5urU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778622439; c=relaxed/simple; bh=Bt3my+6l00h9cgScvXgngonjEUgxY/cU8mMorKuK7Cg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=C0ZxuwCfQc1xsEYouLA97E2Z8kDeob3lDmBfc1CSGF2q3BUG6iPJNW06rfDPcfCDdAhcReJzr19Co0MVjjNJDiu1Rb9DtRRh9C2+jZaT/+7gujZLVz74zqFPS7xBH7rPOIL3wCzCY01C8C/lXPSfYRph1n5pTGgcQ7ZOpDKPXcU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BhdiPeF2; arc=none smtp.client-ip=209.85.208.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BhdiPeF2" Received: by mail-lj1-f172.google.com with SMTP id 38308e7fff4ca-39393c1b5aaso53940011fa.3 for ; Tue, 12 May 2026 14:47:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778622436; x=1779227236; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=f8+wQM4a4tsMzXZ7biCKDr40TVU55tRrbtX6KIaXn24=; b=BhdiPeF2H+LUvuhsPGvfre25Y+cOAjfuFMmZU7XuTZvqjKff+rD8CPGi9Iq+J1THSA H/lIvKssHhfMug326aaemTeip7YJAPrG49nRCAoYrq34i+7j049pW6pqyKXzE2/HHB3L 0JnrdmtyZn/TtviCdXHZ7Dv6kOdHptnvDbf6x/78mKld1ZVXyEBh3nSvxW7wtWMMbcsq DSDso8i6fiBjR4+XLj7y+Wozt/v6bt0UbQjr/7dr37NpsfZ5RbOzDiaAeOBd5izdyBWA NU4hLQJkNdCZJyEpene2ZpksUT5mWaKMgT8vSTRabntTY1U+CDDf+QbwDk2WQ7boiRFd uBeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778622436; x=1779227236; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=f8+wQM4a4tsMzXZ7biCKDr40TVU55tRrbtX6KIaXn24=; b=f8h/hwaHVMFVZO3MezxyQLNAn0mTjo4yQ5ATy2vxpisThhVUYVzSYBptekL4O/lfCF lAt802r/3+M04ozxN3ktVMNf6CzC7Z936nj/AnTQbjBQUdNrqcZ2rCLYCHzJX1vKLYqX YmS8/r/OtyRIRc4DgPkNzahJaIKSu00slAk2wMtbEgjTviIfr2BxeVZYlckxpJdU25V3 MI0MyMTZtfifz05+7Q30vMOH8KUIjEOxH1HdRYy7FjImyRbJl2qanor7IiEVmWInkCZN kniLCGm6pn77vJ6xRbQunzg0SpX5I8WuRAaABkQEGIY2fat/8vtnbvVNwgyr5bbHwBTN S5cA== X-Forwarded-Encrypted: i=1; AFNElJ+7AXPd2PBUhIFzQuNtbA9q7N4SSgXh8L9rZtTcFVLxTTuSLXinMci4GXgVr4MItzTIY93SFhtF/GYSBQY=@vger.kernel.org X-Gm-Message-State: AOJu0Yy3IZcQZPlsHSZBi6qlZlNRHAw//Ej6iuFgVNCdw3swsr+TycEu rG63HFMqhaweIwh7+uZmKMNvqUVgGRKv5viZlFPSTtWhTsBHdVJIfyC1 X-Gm-Gg: Acq92OFXOaKgerzNYuM2tuxDzuMLY26bKHWpwC96wBdOw8lAOwQbWGj6XN/MOMCKD+w SULMtjU9IKuSlF10cIWfELoku33jx7NcEBFSDWI/c/K8FcGxeQf+B5jWIicvbt3pQ6DzPM1R8G7 4Qx2FYovs0oMGgA9Hbjr8CxkoKLZiBfDixYDhc1c4GFg6CJEXAZyuqhtAaT6YLWU+YWbhKE+SwS ezpINJIqdzDbMCebOxL7BsifG9+LglHwTnzJe0WLRAF9YLubHkjjKaN2vfZkczXkHf6FGeKoLVz IdZE/mRRVl0Jz/ATPay7led0f+Dd7KK0b5nxF3SsXK7yDiFjngdx7hOviJ/eyYSC846tBuON2ht JG4++JScR/DFQzBA1nb++B7qgJN5+u+T0MTXlm/GQ8CmXW6KZLNZdPpUbBIwqXxUEO9c0ZB/Yop Zj1X8Lvzc8t5upgsK9YORjqy2ZyBs= X-Received: by 2002:a2e:be06:0:b0:394:44cc:c944 with SMTP id 38308e7fff4ca-3944b727769mr2238831fa.27.1778622435870; Tue, 12 May 2026 14:47:15 -0700 (PDT) Received: from localhost ([2001:863:361:c304:f117:a539:6ce3:fb03]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-393f6144071sm34373081fa.32.2026.05.12.14.47.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 14:47:15 -0700 (PDT) From: Louis Sautier To: "Martin K. Petersen" , "James E.J. Bottomley" , Sathya Prakash , Sreekanth Reddy , Suganath Prabu Subramani , Ranjan Kumar Cc: Guenter Roeck , Jonathan Corbet , Shuah Khan , MPT-FusionLinux.pdl@broadcom.com, linux-scsi@vger.kernel.org, linux-hwmon@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] scsi: mpt3sas: add IO Unit Page 7 config accessor Date: Tue, 12 May 2026 23:47:02 +0200 Message-ID: <20260512214703.655633-2-sautier.louis@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260512214703.655633-1-sautier.louis@gmail.com> References: <20260512214703.655633-1-sautier.louis@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add mpt3sas_config_get_iounit_pg7(), mirroring the existing iounit page accessors. Used by the hwmon driver added in the following patch to read the IOC and board temperatures. Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Louis Sautier --- drivers/scsi/mpt3sas/mpt3sas_base.h | 2 ++ drivers/scsi/mpt3sas/mpt3sas_config.c | 36 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt= 3sas_base.h index d4597d058705..c655742d0dde 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -1904,6 +1904,8 @@ int mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAP= TER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage3_t *config_page, u16 sz); int mpt3sas_config_set_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigR= eply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page); +int mpt3sas_config_get_iounit_pg7(struct MPT3SAS_ADAPTER *ioc, + Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage7_t *config_page); int mpt3sas_config_get_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigR= eply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page); int mpt3sas_config_get_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/m= pt3sas_config.c index 45ac853e1289..ef07825046bc 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_config.c +++ b/drivers/scsi/mpt3sas/mpt3sas_config.c @@ -991,6 +991,42 @@ mpt3sas_config_get_iounit_pg3(struct MPT3SAS_ADAPTER *= ioc, return r; } =20 +/** + * mpt3sas_config_get_iounit_pg7 - obtain iounit page 7 + * @ioc: per adapter object + * @mpi_reply: reply mf payload returned from firmware + * @config_page: contents of the config page + * Context: sleep. + * + * Return: 0 for success, non-zero for failure. + */ +int +mpt3sas_config_get_iounit_pg7(struct MPT3SAS_ADAPTER *ioc, + Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage7_t *config_page) +{ + Mpi2ConfigRequest_t mpi_request; + int r; + + memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); + mpi_request.Function =3D MPI2_FUNCTION_CONFIG; + mpi_request.Action =3D MPI2_CONFIG_ACTION_PAGE_HEADER; + mpi_request.Header.PageType =3D MPI2_CONFIG_PAGETYPE_IO_UNIT; + mpi_request.Header.PageNumber =3D 7; + mpi_request.Header.PageVersion =3D MPI2_IOUNITPAGE7_PAGEVERSION; + ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); + r =3D _config_request(ioc, &mpi_request, mpi_reply, + MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); + if (r) + goto out; + + mpi_request.Action =3D MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; + r =3D _config_request(ioc, &mpi_request, mpi_reply, + MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, + sizeof(*config_page)); + out: + return r; +} + /** * mpt3sas_config_get_iounit_pg8 - obtain iounit page 8 * @ioc: per adapter object --=20 2.54.0 From nobody Fri Jun 12 20:20:17 2026 Received: from mail-lj1-f177.google.com (mail-lj1-f177.google.com [209.85.208.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA4CF392C52 for ; Tue, 12 May 2026 21:47:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778622443; cv=none; b=lyYDmkgbGcKCvjJ5F8Dm6/+T6+1wiyIwpnLCy6wF+c/rw+ErwD20t7Ezuxk3WT4i7dzqyOYF89KiWAeRIi6ChfYl+36eYfciHYcS2Q7Rlhd18UNmB40GqwtraF3CnLnjEngvq1c0VmC5x0LV7tIkJV7iJSkp2xqMEKs3UfXsZKc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778622443; c=relaxed/simple; bh=saC92KOxxM4It5KC/uWNvs0ap5oDnK1CCA3MZLPfBqA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MkFF/Jd6DntZDRYiKgmbMLsr+CQZX815faU4YNZJYjbio/MpQQEGtt4B5tXRr6ibneU5JpUH9byLvrikdtxk0Z12JOVTPFjXuQBEe82mV1+/bZweUkjSCiov89peVEkPG5T/H8j0RmJamvJsFm3pqrGVL+qArWids5EwHmYRg6I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lq0DsB7B; arc=none smtp.client-ip=209.85.208.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lq0DsB7B" Received: by mail-lj1-f177.google.com with SMTP id 38308e7fff4ca-393800f638bso47225361fa.1 for ; Tue, 12 May 2026 14:47:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778622439; x=1779227239; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ke/sZb9uK1j6VoXezaQMAEZyW4dQawkEtVgjASGCtGQ=; b=lq0DsB7BG3zHrhbb7MDeXA+XPmWmngZX2H6JNiP2UicTFIdubirbtaXN360wwfLBpm fFp8LiWXK0tYMvAQxn+Jca2Krkg/HhAYPzKjKlGGC2MumYQgCRTaG10xQN4oJUlNO0gc HDRaJFIP2yQ21bkgdQ43AoJJw0Cci9xAIuTAIyHcJk5Vu0uGdDLkhoLZe4thCZ1YDRwp ekUkEd6jy1As0slq5TTI6TvYXPsnbC/D1B0Ao8VaRWOFtvvjt7p1mdIIsYy3GZkAKAH6 bspxEyYz96gnFU3x40PfMJrXN+hNR/B3wmP0R9eGfsLAyaHuYlpGc+ZEyFmdOfsz4tbG PUjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778622439; x=1779227239; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ke/sZb9uK1j6VoXezaQMAEZyW4dQawkEtVgjASGCtGQ=; b=fvx9vPbH7fw/mELdaYBVf8NDcaESIltZzwTdknHuH4OvJH535i18m15Y/B1MZVAVSA qktDcgh4o6lM7046C8EMv0too5fDbVFJvq+V4wOlwFoGnLOyY50wQlD59VVGyDhsH27/ Owk5SnhreMgUmc8kJMxuX3mSTETn+pg6zDLJiEWeflMQCEwapbgtF5nV0nyEJZAswcg8 vu7F98/22PnnAq4Rfq8pApN0PzzWOJkH0dQwd7FbghYFkisbqVMwQAVH6fbfx9qMIJgn +xy4dKU9GIW/KSRbtuPbRGNaafU3v36a6Vq3YfWuLXIQMG8RXfNRVf9HwbSSy5qtN4Jh +eLQ== X-Forwarded-Encrypted: i=1; AFNElJ+4A2liTnJPD0TP5upQlI91Me9A0vAezedgf4WVT/NJaxLKaKc7rb9skIkZDeVmcdociN0+pnBu/mhE+Jk=@vger.kernel.org X-Gm-Message-State: AOJu0YyYl8txPnEwTk3Vp/QcDMXcaWykG2fEAx0HZWiTwwhkJ4iAQZRL bI6U89fmvTOZik27GNFL2t8E96SZMO23eeLqyLqqktM4tzlQrz6uUO38 X-Gm-Gg: Acq92OHhK1niA82h6G7U40CHmnLOa3+/Ei36IJrQ65IDUP1WDVIcjZ277c/xC63h1NO DqnG1Q7ocgB9XIQ5OoLWal1Hi/MtEWjKysSjC9ORyOkgYD8XZOzDdCA2eHvKpr63h1hfGLS57An Y+yEEpxmqxttk0EA+Gs88druViMOiY1wzKPW2qhwJZTFw38Y0BLsXDUIMJc9W+tBWnoe4E06V6Z e2FtCOWfkLDK7JROsEGp962htD+++elofMaaTFDaWAILzV9MXS3/CPvCMIjwOZ/+DTS1n6ePyHh RIJjZciYliJnTmYLQ4kQ09iNgzvIzI+L0UMxgJUXTe7u1Dx6b7gQfU9RcJN7TcowWibTtUYiSPB PB+D+O2nm2ILr/TsSknLSYCRS3pMEBhYhLX4MIVFGdORnxpxJ401/ym6TIUhYlVPB3p2m2FuNBU NuJErxHFCh2ii1WTYBUOW4Icb+VgP0GzNkLOLWiw== X-Received: by 2002:a2e:8a86:0:b0:38e:83a6:d37 with SMTP id 38308e7fff4ca-3944b5aeab4mr1964531fa.13.1778622438869; Tue, 12 May 2026 14:47:18 -0700 (PDT) Received: from localhost ([2001:863:361:c304:f117:a539:6ce3:fb03]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-393f6144071sm34373081fa.32.2026.05.12.14.47.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 14:47:18 -0700 (PDT) From: Louis Sautier To: "Martin K. Petersen" , "James E.J. Bottomley" , Sathya Prakash , Sreekanth Reddy , Suganath Prabu Subramani , Ranjan Kumar Cc: Guenter Roeck , Jonathan Corbet , Shuah Khan , MPT-FusionLinux.pdl@broadcom.com, linux-scsi@vger.kernel.org, linux-hwmon@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/2] scsi: mpt3sas: add hwmon support Date: Tue, 12 May 2026 23:47:03 +0200 Message-ID: <20260512214703.655633-3-sautier.louis@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260512214703.655633-1-sautier.louis@gmail.com> References: <20260512214703.655633-1-sautier.louis@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Expose the IOC and board temperature sensors of LSI / Broadcom SAS HBAs through hwmon. Readings come from MPI IO Unit Page 7 via the accessor added in the preceding patch. The same fields are exposed by Broadcom's userspace tooling through the /dev/mpt[23]ctl ioctl path (typically root-only): IOCTemperature and BoardTemperature in lsiutil; ROC and Controller in storcli. With this driver, sensors(1) shows them unprivileged: $ sensors mpt3sas-pci-0200 mpt3sas-pci-0200 Adapter: PCI adapter IOC: +42.0=C2=B0C Each channel is gated independently by its *TemperatureUnits field through is_visible(); cards that populate only one sensor expose only one input file, and cards that populate neither do not register an hwmon device. Built into mpt3sas.ko under a new CONFIG_SCSI_MPT3SAS_HWMON Kconfig option. Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Louis Sautier --- Documentation/hwmon/index.rst | 1 + Documentation/hwmon/mpt3sas.rst | 57 ++++++++ MAINTAINERS | 1 + drivers/scsi/mpt3sas/Kconfig | 9 ++ drivers/scsi/mpt3sas/Makefile | 2 + drivers/scsi/mpt3sas/mpt3sas_base.h | 17 +++ drivers/scsi/mpt3sas/mpt3sas_hwmon.c | 200 +++++++++++++++++++++++++++ drivers/scsi/mpt3sas/mpt3sas_scsih.c | 6 + 8 files changed, 293 insertions(+) create mode 100644 Documentation/hwmon/mpt3sas.rst create mode 100644 drivers/scsi/mpt3sas/mpt3sas_hwmon.c diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst index 8b655e5d6b68..106f87fa8b18 100644 --- a/Documentation/hwmon/index.rst +++ b/Documentation/hwmon/index.rst @@ -193,6 +193,7 @@ Hardware Monitoring Kernel Drivers mp9941 mp9945 mpq8785 + mpt3sas nct6683 nct6775 nct7363 diff --git a/Documentation/hwmon/mpt3sas.rst b/Documentation/hwmon/mpt3sas.= rst new file mode 100644 index 000000000000..3a260a389d6d --- /dev/null +++ b/Documentation/hwmon/mpt3sas.rst @@ -0,0 +1,57 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Kernel driver mpt3sas +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Supported chips: + + * LSI / Broadcom / Avago SAS HBAs handled by the mpt3sas driver, + such as the 9300, 9400, and 9500 series. + + Prefix: ``mpt3sas`` + + +Description +----------- + +The mpt3sas driver exposes the IOC and board temperature sensors of +LSI / Broadcom SAS HBAs through the hwmon interface. +Either or both sensors may be absent depending on the card; the +corresponding sysfs files only appear when the firmware reports the +sensor as present, and cards that report neither sensor do not +register an hwmon device at all. + + +Sysfs entries +------------- + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Name Description +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +temp1_input IOC temperature (mC) +temp1_label "IOC" +temp2_input Board temperature (mC) +temp2_label "Board" +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + + +Cross-reference with vendor tooling +----------------------------------- + +The hwmon channels correspond to fields reported by Broadcom's +proprietary tools as follows: + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D +hwmon label lsiutil storcli +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D +``IOC`` (temp1) ``IOCTemperature`` ``ROC temperature`` +``Board`` (temp2) ``BoardTemperature`` ``Controller temperature`` +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D + +With lsiutil:: + + lsiutil -pN -a 25,2,0,0 + +With storcli:: + + storcli /cN show temperature diff --git a/MAINTAINERS b/MAINTAINERS index b2040011a386..e084f710f436 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15154,6 +15154,7 @@ L: MPT-FusionLinux.pdl@broadcom.com L: linux-scsi@vger.kernel.org S: Supported W: http://www.avagotech.com/support/ +F: Documentation/hwmon/mpt3sas.rst F: drivers/message/fusion/ F: drivers/scsi/mpt3sas/ =20 diff --git a/drivers/scsi/mpt3sas/Kconfig b/drivers/scsi/mpt3sas/Kconfig index c299f7e078fb..638acd2c6623 100644 --- a/drivers/scsi/mpt3sas/Kconfig +++ b/drivers/scsi/mpt3sas/Kconfig @@ -73,6 +73,15 @@ config SCSI_MPT3SAS_MAX_SGE can be 256. However, it may decreased down to 16. Decreasing this parameter will reduce memory requirements on a per controller instance. =20 +config SCSI_MPT3SAS_HWMON + bool "LSI MPT Fusion SAS hwmon support" + depends on SCSI_MPT3SAS && HWMON + depends on !(SCSI_MPT3SAS=3Dy && HWMON=3Dm) + help + Say Y here to expose the IOC and board temperature sensors of + LSI / Broadcom SAS HBAs (such as the 9300, 9400, and 9500 series) + through hwmon. See Documentation/hwmon/mpt3sas.rst for details. + config SCSI_MPT2SAS tristate "Legacy MPT2SAS config option" default n diff --git a/drivers/scsi/mpt3sas/Makefile b/drivers/scsi/mpt3sas/Makefile index e76d994dbed3..9a2f3ce4158a 100644 --- a/drivers/scsi/mpt3sas/Makefile +++ b/drivers/scsi/mpt3sas/Makefile @@ -9,3 +9,5 @@ mpt3sas-y +=3D mpt3sas_base.o \ mpt3sas_trigger_diag.o \ mpt3sas_warpdrive.o \ mpt3sas_debugfs.o \ + +mpt3sas-$(CONFIG_SCSI_MPT3SAS_HWMON) +=3D mpt3sas_hwmon.o diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt= 3sas_base.h index c655742d0dde..63252f30343b 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -1629,6 +1629,7 @@ struct MPT3SAS_ADAPTER { u8 is_aero_ioc; struct dentry *debugfs_root; struct dentry *ioc_dump; + struct mpt3sas_hwmon *hwmon; PUT_SMID_IO_FP_HIP put_smid_scsi_io; PUT_SMID_IO_FP_HIP put_smid_fast_path; PUT_SMID_IO_FP_HIP put_smid_hi_priority; @@ -2049,6 +2050,22 @@ void mpt3sas_destroy_debugfs(struct MPT3SAS_ADAPTER = *ioc); void mpt3sas_init_debugfs(void); void mpt3sas_exit_debugfs(void); =20 +#if IS_ENABLED(CONFIG_SCSI_MPT3SAS_HWMON) +int mpt3sas_hwmon_register(struct MPT3SAS_ADAPTER *ioc); +void mpt3sas_hwmon_unregister(struct MPT3SAS_ADAPTER *ioc); +#else +static inline int +mpt3sas_hwmon_register(struct MPT3SAS_ADAPTER *ioc) +{ + return 0; +} + +static inline void +mpt3sas_hwmon_unregister(struct MPT3SAS_ADAPTER *ioc) +{ +} +#endif + /** * _scsih_is_pcie_scsi_device - determines if device is an pcie scsi device * @device_info: bitfield providing information about the device. diff --git a/drivers/scsi/mpt3sas/mpt3sas_hwmon.c b/drivers/scsi/mpt3sas/mp= t3sas_hwmon.c new file mode 100644 index 000000000000..26227a992f35 --- /dev/null +++ b/drivers/scsi/mpt3sas/mpt3sas_hwmon.c @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Hardware monitoring (hwmon) support for the LSI / Broadcom mpt3sas + * SAS HBA driver. Exposes the IOC and board temperature sensors by + * reading MPI IO Unit Page 7. + */ + +#include +#include +#include +#include + +#include "mpt3sas_base.h" + +struct mpt3sas_hwmon { + struct MPT3SAS_ADAPTER *ioc; + struct device *hwmon_dev; + bool ioc_present; + bool board_present; +}; + +/* + * Convert a (raw, units) reading to millidegrees Celsius. + * Returns -ENODATA when the sensor reports "not present" or + * unknown units. Temperature values are interpreted as signed + * two's-complement integers. + * + * The MPI2_IOUNITPAGE7_IOC_TEMP_* and MPI2_IOUNITPAGE7_BOARD_TEMP_* + * defines in mpi2_cnfg.h share the same values; the IOC ones are + * used for both channels. + */ +static int +_hwmon_to_mdegc(s16 raw, u8 units, long *out) +{ + switch (units) { + case MPI2_IOUNITPAGE7_IOC_TEMP_CELSIUS: + *out =3D (long)raw * 1000; + return 0; + case MPI2_IOUNITPAGE7_IOC_TEMP_FAHRENHEIT: + /* (F - 32) * 5 / 9, expressed in milli-units */ + *out =3D ((long)raw - 32) * 5000 / 9; + return 0; + default: + return -ENODATA; + } +} + +static umode_t +_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type, + u32 attr, int channel) +{ + const struct mpt3sas_hwmon *h =3D drvdata; + + if (type !=3D hwmon_temp) + return 0; + if (attr !=3D hwmon_temp_input && attr !=3D hwmon_temp_label) + return 0; + if (channel =3D=3D 0 && h->ioc_present) + return 0444; + if (channel =3D=3D 1 && h->board_present) + return 0444; + return 0; +} + +static int +_hwmon_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + struct mpt3sas_hwmon *h =3D dev_get_drvdata(dev); + Mpi2ConfigReply_t mpi_reply; + Mpi2IOUnitPage7_t page; + int r; + + if (type !=3D hwmon_temp || attr !=3D hwmon_temp_input) + return -EOPNOTSUPP; + + r =3D mpt3sas_config_get_iounit_pg7(h->ioc, &mpi_reply, &page); + if (r) + return r; + + if (channel =3D=3D 0) + return _hwmon_to_mdegc((s16)le16_to_cpu(page.IOCTemperature), + page.IOCTemperatureUnits, val); + if (channel =3D=3D 1) + return _hwmon_to_mdegc((s16)le16_to_cpu(page.BoardTemperature), + page.BoardTemperatureUnits, val); + return -EOPNOTSUPP; +} + +static const char * const mpt3sas_hwmon_temp_labels[] =3D { + "IOC", + "Board", +}; + +static int +_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, const char **str) +{ + if (type !=3D hwmon_temp || attr !=3D hwmon_temp_label) + return -EOPNOTSUPP; + *str =3D mpt3sas_hwmon_temp_labels[channel]; + return 0; +} + +static const struct hwmon_channel_info * const mpt3sas_hwmon_info[] =3D { + HWMON_CHANNEL_INFO(temp, + HWMON_T_INPUT | HWMON_T_LABEL, + HWMON_T_INPUT | HWMON_T_LABEL), + NULL, +}; + +static const struct hwmon_ops mpt3sas_hwmon_ops =3D { + .is_visible =3D _hwmon_is_visible, + .read =3D _hwmon_read, + .read_string =3D _hwmon_read_string, +}; + +static const struct hwmon_chip_info mpt3sas_hwmon_chip_info =3D { + .ops =3D &mpt3sas_hwmon_ops, + .info =3D mpt3sas_hwmon_info, +}; + +/** + * mpt3sas_hwmon_register - register an hwmon device for the IOC + * @ioc: per adapter object + * Context: sleep. + * + * Succeeds without registering when no temperature sensors are present, + * so cards without thermal monitoring do not expose an empty hwmon node. + * Paired with mpt3sas_hwmon_unregister() from the driver's remove path. + * + * Return: 0 for success, non-zero for failure. + */ +int +mpt3sas_hwmon_register(struct MPT3SAS_ADAPTER *ioc) +{ + struct device *parent =3D &ioc->pdev->dev; + struct mpt3sas_hwmon *h; + struct device *hwdev; + Mpi2ConfigReply_t mpi_reply; + Mpi2IOUnitPage7_t page; + int r; + + h =3D kzalloc_obj(*h); + if (!h) + return -ENOMEM; + + h->ioc =3D ioc; + + r =3D mpt3sas_config_get_iounit_pg7(ioc, &mpi_reply, &page); + if (r) { + kfree(h); + return r; + } + + h->ioc_present =3D page.IOCTemperatureUnits !=3D MPI2_IOUNITPAGE7_IOC_TEM= P_NOT_PRESENT; + h->board_present =3D page.BoardTemperatureUnits !=3D MPI2_IOUNITPAGE7_BOA= RD_TEMP_NOT_PRESENT; + + /* + * A page where both *TemperatureUnits are NOT_PRESENT covers + * two cases: cards that genuinely lack sensors, and firmware + * errors that left the page zero-filled (the accessor mirrors + * _config_request() behaviour). Either way: skip registration. + */ + if (!h->ioc_present && !h->board_present) { + kfree(h); + return 0; + } + + hwdev =3D hwmon_device_register_with_info(parent, "mpt3sas", h, + &mpt3sas_hwmon_chip_info, + NULL); + if (IS_ERR(hwdev)) { + kfree(h); + return PTR_ERR(hwdev); + } + + h->hwmon_dev =3D hwdev; + ioc->hwmon =3D h; + return 0; +} + +/** + * mpt3sas_hwmon_unregister - tear down the hwmon device, if any + * @ioc: per adapter object + * + * Safe to call when registration was skipped (no sensors) or + * failed; in those cases ioc->hwmon is NULL and this is a no-op. + */ +void +mpt3sas_hwmon_unregister(struct MPT3SAS_ADAPTER *ioc) +{ + struct mpt3sas_hwmon *h =3D ioc->hwmon; + + if (!h) + return; + hwmon_device_unregister(h->hwmon_dev); + kfree(h); + ioc->hwmon =3D NULL; +} diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mp= t3sas_scsih.c index 12caffeed3a0..dea78688cc9b 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -12562,6 +12562,7 @@ static void scsih_remove(struct pci_dev *pdev) /* release all the volumes */ _scsih_ir_shutdown(ioc); mpt3sas_destroy_debugfs(ioc); + mpt3sas_hwmon_unregister(ioc); sas_remove_host(shost); list_for_each_entry_safe(raid_device, next, &ioc->raid_device_list, list) { @@ -13651,6 +13652,11 @@ _scsih_probe(struct pci_dev *pdev, const struct pc= i_device_id *id) } =20 scsi_scan_host(shost); + + if (mpt3sas_hwmon_register(ioc)) + ioc_warn(ioc, + "hwmon registration failed; temperatures not exposed\n"); + mpt3sas_setup_debugfs(ioc); return 0; out_add_shost_fail: --=20 2.54.0