From nobody Wed Mar 09 20:52:51 2022 X-Original-To: dev-commits-src-branches@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 6FC151A144CE; Wed, 9 Mar 2022 20:52:51 +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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KDPXg2l1Yz3QDG; Wed, 9 Mar 2022 20:52:51 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1646859171; 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=AXDiYdJSNE0P2M63RDluiQ+w3oMQA4P5kcbZMGYUzWo=; b=IufvpA6h+wvh0dLV6pKDH81pEEj4gvttTLS+PyasLVW12wAUl1T2vdwQYVzEU5wXfoxOSu DnESdXn+vVmBT1sQnpUvBo19S35Q9PJym6VJ/a3rOO+7UDDw33/DTJqTJiUvNbkvY4ROjJ GDXBDTL7SV4xvngV/FGtivM4C0dh4qlTQm0hS3VpfSfSSCMnF0ll6k7kVMpnkWKSE0nCpe gL5xL9jKK/nqqoMZSX0Gpzo9j0A2ptKv4ySMoNaWMwFlYcy7hfsk2e5tzxHe4UrlRppEm2 31uar9hIEuJEGauWLMSWDHj9mP1PPWtmrCrU/LfhNc8OcfKJJrnLgZmG11QH+w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 3DAC418027; Wed, 9 Mar 2022 20:52:51 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 229Kqp49062124; Wed, 9 Mar 2022 20:52:51 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 229Kqp7m062123; Wed, 9 Mar 2022 20:52:51 GMT (envelope-from git) Date: Wed, 9 Mar 2022 20:52:51 GMT Message-Id: <202203092052.229Kqp7m062123@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Warner Losh Subject: git: 327da43602cc - stable/13 - camcontrol: Force a rescan of the lun after firmware download. List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: imp X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 327da43602cc40836d0858e22e200f5e39edae4b Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1646859171; 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=AXDiYdJSNE0P2M63RDluiQ+w3oMQA4P5kcbZMGYUzWo=; b=uHty2wTv2eQOllxQzdVJ5iHZBxZOYCZMFbURilg47hZHki2DcTFCUJNGCz4VzWURB/Vh/K DKqEAT71/JjZld/yv/sxvYk6ESNXEEYV5NEvLTb/L73JB+PqLd0JYZ532j07BOgpXT4Jho pNLU9FNjTgj+SUf9+YKp90Maf0O5zwVCghn6VONQurvED4r3FGzDutxT5yFehDsIzCrtnn 0WuWgMZlD9NttzCMspVIuz4jogU9EWLFHxjqbhgCKqDOB9/bS117WzroH4gkEKg6GAlmzC fDgRSdjCXfM4MZCnjWLGoGcvJII8i6u4jfBjxd5HtYueMdTmo+hAap0Nh7zKKg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1646859171; a=rsa-sha256; cv=none; b=SnpBe+IYwQBsnvRLQCvh1EUjGog7aOgJ4A1x0zLMiBaKB3Fq0c2gO2Xl0Tm6rXIP6j4nLU jTGlPcih3jyBXXrfIFhvgwPEhTvgx+Nz2UG+N85H0YcwPJT0NrPsQD6ZJm1VgrSx0hN7PK SR+2skiKHv5wRFtX/9BOq49L4iv8oeXhVqglx9HKY7n1mh+kkjEPVLfc7WtZB3OTcn6t8b 5+Np1yZ/0AnCuZcyqGpWiC2X4ey/EdiidvTSzhH6+1NwEYVN1/UASzYHEWPRNP9/1i3b2l mE2USDRSjZJNvwMYWiJq3HpgUEBMgqzGmaLofPNNWP645vUcbPV22mF1jejQ8w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=327da43602cc40836d0858e22e200f5e39edae4b commit 327da43602cc40836d0858e22e200f5e39edae4b Author: Warner Losh AuthorDate: 2022-02-22 17:34:36 +0000 Commit: Warner Losh CommitDate: 2022-03-09 20:52:22 +0000 camcontrol: Force a rescan of the lun after firmware download. After downloading the firmware to a device, it's inquiry data likely will change. Force a rescan of the target with the CAM_EXPECT_INQ_CHANGE flag to get it to record the new inqury data as being expected. This avoids the need for a 'camcontrol rescan' on the device which detaches and re-attaches the disk (da, ada) device. This brings fwdownload up to nvmecontrol's ability to do the same thing w/o changing the exposed nvme/nvd/nda device. We scan the target and not the LUN because dual actuator drives have multiple LUNs, but the firmware is global across many vendors' drives (and the so far theoretical ones that aren't won't be harmed by the rescan). Since the underlying struct disk is now preserved accross this operation, it's now possible to upgrade firmware of a root device w/o crashing the system. On systems that are quite busy, the worst that happens is that certain operaions are reported cancelled when the new firmware is activated. These operations are retried with the normal CAM recovery mechanisms and will work on the retry. The only visible hiccup is the time that new firmware is flashing / initializing. One should not consider this operation completely risk free, however, since not all drives are well behaved after a firmware download. MFC After: 1 week Relnotes: yes Sponsored by: Netflix Feedback by: mav Differential Revision: https://reviews.freebsd.org/D34325 (cherry picked from commit 9835900cb95bcd068774934961fb1419719d595b) --- sbin/camcontrol/fwdownload.c | 67 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/sbin/camcontrol/fwdownload.c b/sbin/camcontrol/fwdownload.c index 87aef6d3c240..56ccaaac1e59 100644 --- a/sbin/camcontrol/fwdownload.c +++ b/sbin/camcontrol/fwdownload.c @@ -57,12 +57,15 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include #include +#include #include +#include #include #include @@ -764,6 +767,67 @@ bailout: return (retval); } +/* + * After the firmware is downloaded, we know the sense data has changed (or is + * likely to change since it contains the firmware version). Rescan the target + * with a flag to tell the kernel it's OK. This allows us to continnue using the + * old periph/disk in the kernel, which is less disruptive. We rescan the target + * because multilun devices usually update all the luns after the first firmware + * download. + */ +static int +fw_rescan_lun(struct cam_device *dev, bool printerrors) +{ + union ccb ccb; + int fd; + target_id_t target; + uint32_t bus; + + /* Can only send XPT_SCAN_TGT via /dev/xpt, not pass device in *dev */ + if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { + warnx("error opening transport layer device %s\n", + XPT_DEVICE); + warn("%s", XPT_DEVICE); + return (1); + } + + /* Fill in the bus and target IDs as they don't seem to be in *dev */ + bzero(&ccb, sizeof(union ccb)); + ccb.ccb_h.func_code = XPT_GDEVLIST; + strlcpy(ccb.cgdl.periph_name, dev->device_name, sizeof(ccb.cgdl.periph_name)); + ccb.cgdl.unit_number = dev->dev_unit_num; + if (cam_send_ccb(dev, &ccb) < 0) { + warn("send_ccb GDEVLIST failed\n"); + close(fd); + return (1); + } + bus = ccb.ccb_h.path_id; + target = ccb.ccb_h.target_id; + + /* Rescan the target */ + bzero(&ccb, sizeof(union ccb)); + ccb.ccb_h.func_code = XPT_SCAN_TGT; + ccb.ccb_h.path_id = bus; + ccb.ccb_h.target_id = target; + ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; + ccb.crcn.flags = CAM_EXPECT_INQ_CHANGE; + ccb.ccb_h.pinfo.priority = 5; /* run this at a low priority */ + + if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) { + warn("CAMIOCOMMAND XPT_SCAN_TGT ioctl failed"); + close(fd); + return (1); + } + if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + warn("Can't send rescan lun"); + if (printerrors) + cam_error_print(dev, &ccb, CAM_ESF_ALL, CAM_EPF_ALL, + stderr); + return (1); + } + return (0); +} + /* * Download firmware stored in buf to cam_dev. If simulation mode * is enabled, only show what packet sizes would be sent to the @@ -919,6 +983,9 @@ bailout: if (quiet == 0) progress_complete(&progress, size - img_size); cam_freeccb(ccb); + if (retval == 0 && !sim_mode) { + fw_rescan_lun(cam_dev, printerrors); + } return (retval); }