From nobody Thu Apr 30 09:18:12 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4g5pVy19TWz6bRRH for ; Thu, 30 Apr 2026 09:18:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4g5pVy0cRZz45Sp for ; Thu, 30 Apr 2026 09:18:18 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1777540698; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ncXjZLwam4Hbrq1g76x51+sqbN82K/3DZ10jyWtflL8=; b=nxIJUgAXQaa47cvUXrS0XmP2155TiW8K0uhcinJrD3yPJCXyNhjn4TGN2YrXFqB0dhc4OL xND5NjZilIo/huuJu95HWlWsOk6CKoRylnlWIw/n7JMrPd5BK6GFc5yy30nJfr+lk4cJtH 9owg0spRfmX9lHHyk6njZS0Xt90DFaIGlHk0kISWwL+WGsX92Qo1ZSnbWVwDceHMETnIjj kQRPz8CAxa9X5Mx/tKb6YWnfT6WCJ6l4R2wZMLR9vOgbLmh5o5aew5tTad0nm3p0F6ca4p D/T/dVRhDv7g60aocxPPtq0teFHfcACgWM1oSKQnW6HqhFnoyPVrFaIG3MaYwg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1777540698; a=rsa-sha256; cv=none; b=GccYy7ioL7Rz8SLk4AH634AlrAitw1oqSHHarxbbE03lmA5I4/VqPe+l1C9B/RGQR/4wGZ 8Y9TvARK+NWcv2IKbChKWut9VFVRdWMLr57OY8or0PCm8QrDWRFF4I0m8/hXZF8I1uUlRf QgMGfqeptwIgcCtgBKlnSHh2ONyvMm7sh75KCRPWekYFyp1n4hBXo4ryysZiYO1flwSfkr RKHxogpTxitDFcgrEtCqyEdWWaseWr5SWQyiE9Wx4A6MmUdsqqcMGomeJNZxroKtwe8JO1 u4lZmUTSrGiXBRT+DQ1DAuNWxVRr/wIBbVLGEC+vx7K/6AOHssQyxo5YQ7R5mQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1777540698; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ncXjZLwam4Hbrq1g76x51+sqbN82K/3DZ10jyWtflL8=; b=oGS9Q/wNP9xe8XrLvCflEj5J+crxQxXXBCduWhrIrfpPsuRFZFVbtrqlLow6rhf6BfT2Cf lmWqwkDSmPSljB4ClA0fZyTU56bovX1KEnbFhbMieiIMRn47STrbtjB4mrmz6OpjFjbNCA Am2hNLBWbir40t1+U9yzSvfJGm8xP/fFAtCER5kPAYW9b6iSfOyOfFSi0kIEKNAm11mgkI SLO7x1ubIKKVjfVw5wJ/BuI2QQf3eTVwzs+nLor0mH8nDfqI8PgxIhXgno00sGHSp6CHA4 YD7lW+/GqPkKZ+aySO1zYBjlQPoE92b7VEPRYyHSmRHo9w6G4G4oMwnB9oh/Bw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4g5pVy0Btbz1KJw for ; Thu, 30 Apr 2026 09:18:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 416a2 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 30 Apr 2026 09:18:12 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Corvi=?utf-8?Q?n K=C3=B6h?=ne Subject: git: 226b37dc3ad5 - main - dev/ichsmb: disable block buffer if supported List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: corvink X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 226b37dc3ad5641c18f8542c18baea3ea641c5af Auto-Submitted: auto-generated Date: Thu, 30 Apr 2026 09:18:12 +0000 Message-Id: <69f31e54.416a2.7d72e12f@gitrepo.freebsd.org> The branch main has been updated by corvink: URL: https://cgit.FreeBSD.org/src/commit/?id=226b37dc3ad5641c18f8542c18baea3ea641c5af commit 226b37dc3ad5641c18f8542c18baea3ea641c5af Author: Corvin Köhne AuthorDate: 2026-03-30 09:33:20 +0000 Commit: Corvin Köhne CommitDate: 2026-04-30 09:15:18 +0000 dev/ichsmb: disable block buffer if supported In order to improve the efficiency of block read/write calls, Intel has introduced a block buffer. Instead of generating an interrupt after receiving/sending a single byte, the data is buffered in the block buffer. It allows the SMBus controller to generate a single interrupt for the whole transfer. At the moment, we don't support that and don't expect the SMBus controller to behave in that way. Unfortunately, BIOS code can also access the SMBus controller and may enable the block buffer. Poorly written BIOS code may also keep the block buffer enabled breaking our driver. Therefore, we should check if the device supports a block buffer and disable it for every request because we don't know if some BIOS code has reconfigured the SMBus controller in between. Reviewed by: emaste MFC after: 1 week Sponsored by: Beckhoff Automation GmbH & Co. KG Pull Request: https://github.com/freebsd/freebsd-src/pull/2161 --- sys/dev/ichsmb/ichsmb.c | 18 +++++++++++++++ sys/dev/ichsmb/ichsmb_pci.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ sys/dev/ichsmb/ichsmb_reg.h | 3 +++ sys/dev/ichsmb/ichsmb_var.h | 3 +++ 4 files changed, 78 insertions(+) diff --git a/sys/dev/ichsmb/ichsmb.c b/sys/dev/ichsmb/ichsmb.c index e40a8a8a3886..0df757d9cc0e 100644 --- a/sys/dev/ichsmb/ichsmb.c +++ b/sys/dev/ichsmb/ichsmb.c @@ -395,6 +395,15 @@ ichsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) sc->block_write = true; mtx_lock(&sc->mutex); + /* + * We don't expect the block buffer to be enabled. However, BIOS code + * might enable it and doesn't restore it at any time, so we should + * ensure it's disabled before sending an SMBus command. + */ + if (sc->features & ICHSMB_FEATURE_BLOCK_BUFFER) { + bus_write_1(sc->io_res, ICH_AUX_CNT, + bus_read_1(sc->io_res, ICH_AUX_CNT) & ~ICH_AUX_CNT_E32B); + } sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BLOCK; bus_write_1(sc->io_res, ICH_XMIT_SLVA, slave | ICH_XMIT_SLVA_WRITE); @@ -424,6 +433,15 @@ ichsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) sc->block_write = false; mtx_lock(&sc->mutex); + /* + * We don't expect the block buffer to be enabled. However, BIOS code + * might enable it and doesn't restore it at any time, so we should + * ensure it's disabled before sending an SMBus command. + */ + if (sc->features & ICHSMB_FEATURE_BLOCK_BUFFER) { + bus_write_1(sc->io_res, ICH_AUX_CNT, + bus_read_1(sc->io_res, ICH_AUX_CNT) & ~ICH_AUX_CNT_E32B); + } sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BLOCK; bus_write_1(sc->io_res, ICH_XMIT_SLVA, slave | ICH_XMIT_SLVA_READ); diff --git a/sys/dev/ichsmb/ichsmb_pci.c b/sys/dev/ichsmb/ichsmb_pci.c index 7d6d94dbb4a4..af3e0f004b88 100644 --- a/sys/dev/ichsmb/ichsmb_pci.c +++ b/sys/dev/ichsmb/ichsmb_pci.c @@ -129,106 +129,153 @@ static const struct pci_device_table ichsmb_devices[] = { { PCI_DEV(PCI_VENDOR_INTEL, ID_82801CA), PCI_DESCR("Intel 82801CA (ICH3) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_82801DC), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 82801DC (ICH4) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_82801EB), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 82801EB (ICH5) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_82801FB), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 82801FB (ICH6) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_82801GB), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 82801GB (ICH7) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_82801H), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 82801H (ICH8) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_82801I), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 82801I (ICH9) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_82801GB), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 82801GB (ICH7) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_82801H), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 82801H (ICH8) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_82801I), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 82801I (ICH9) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_EP80579), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel EP80579 SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_82801JI), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 82801JI (ICH10) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_82801JD), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 82801JD (ICH10) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_PCH), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel PCH SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_6300ESB), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 6300ESB (ICH) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_631xESB), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel 631xESB/6321ESB (ESB2) SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_DH89XXCC), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel DH89xxCC SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_PATSBURG), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Patsburg SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_CPT), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Cougar Point SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_PPT), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Panther Point SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_AVOTON), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Avoton SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_LPT), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Lynx Point SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_LPTLP), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Lynx Point-LP SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_WCPT), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Wildcat Point SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_WCPTLP), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Wildcat Point-LP SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_BAYTRAIL), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Baytrail SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_BRASWELL), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Braswell SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_COLETOCRK), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Coleto Creek SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_WELLSBURG), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Wellsburg SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_SRPT), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Sunrise Point-H SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_SRPTLP), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Sunrise Point-LP SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_DENVERTON), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Denverton SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_BROXTON), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Broxton SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_LEWISBURG), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Lewisburg SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_LEWISBURG2), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Lewisburg SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_KABYLAKE), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Kaby Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_CANNONLAKE), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Cannon Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_COMETLAKE), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Comet Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_COMETLAKE2), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Comet Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_TIGERLAKE), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Tiger Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_TIGERLAKE2), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Tiger Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_ELKHARTLAKE), PCI_DESCR("Intel Elkhart Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_GEMINILAKE), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Gemini Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_CEDARFORK), PCI_DESCR("Intel Cedar Fork SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_ICELAKE), PCI_DESCR("Intel Ice Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_ALDERLAKE), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Alder Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_ALDERLAKE2), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Alder Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_ALDERLAKE3), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Alder Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_RAPTORLAKE), PCI_DESCR("Intel Raptor Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_METEORLAKE), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Meteor Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_METEORLAKE2), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Meteor Lake SMBus controller") }, { PCI_DEV(PCI_VENDOR_INTEL, ID_METEORLAKE3), + .driver_data = (uintptr_t)ICHSMB_FEATURE_BLOCK_BUFFER, PCI_DESCR("Intel Meteor Lake SMBus controller") }, }; @@ -288,6 +335,7 @@ ichsmb_pci_probe(device_t dev) static int ichsmb_pci_attach(device_t dev) { + const struct pci_device_table *tbl; const sc_p sc = device_get_softc(dev); int error; @@ -296,6 +344,12 @@ ichsmb_pci_attach(device_t dev) sc->ich_cmd = -1; sc->dev = dev; + tbl = PCI_MATCH(dev, ichsmb_devices); + if (tbl == NULL) + return (ENXIO); + + sc->features = (uint32_t)tbl->driver_data; + /* Allocate an I/O range */ sc->io_rid = ICH_SMB_BASE; sc->io_res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, diff --git a/sys/dev/ichsmb/ichsmb_reg.h b/sys/dev/ichsmb/ichsmb_reg.h index 78e398a556ef..be3b9e4a899d 100644 --- a/sys/dev/ichsmb/ichsmb_reg.h +++ b/sys/dev/ichsmb/ichsmb_reg.h @@ -84,6 +84,9 @@ #define ICH_D0 0x05 /* host data 0 */ #define ICH_D1 0x06 /* host data 1 */ #define ICH_BLOCK_DB 0x07 /* block data byte */ +#define ICH_AUX_CNT 0x0d /* auxiliary control */ +#define ICH_AUX_CNT_E32B 0x02 /* enable 32 byte buffer */ +#define ICH_AUX_CNT_AAC 0x01 /* automatically append crc */ #endif /* _DEV_ICHSMB_ICHSMB_REG_H_ */ diff --git a/sys/dev/ichsmb/ichsmb_var.h b/sys/dev/ichsmb/ichsmb_var.h index 8aeaf403781b..f16a40be9777 100644 --- a/sys/dev/ichsmb/ichsmb_var.h +++ b/sys/dev/ichsmb/ichsmb_var.h @@ -41,6 +41,8 @@ #include "smbus_if.h" +#define ICHSMB_FEATURE_BLOCK_BUFFER 0x01 /* supports 32 byte block buffer */ + /* Per-device private info */ struct ichsmb_softc { @@ -52,6 +54,7 @@ struct ichsmb_softc { struct resource *irq_res; /* interrupt resource */ int irq_rid; /* interrupt bus id */ void *irq_handle; /* handle for interrupt code */ + uint32_t features; /* supported device features */ /* Device state */ int ich_cmd; /* ich command, or -1 */