diff --git a/share/man/man4/isp.4 b/share/man/man4/isp.4 --- a/share/man/man4/isp.4 +++ b/share/man/man4/isp.4 @@ -24,7 +24,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd October 27, 2023 +.Dd June 24, 2024 .Dt ISP 4 .Os .Sh NAME @@ -141,6 +141,21 @@ .It Va hint.isp. Ns Ar N Ns Va .fwload_disable A hint value to disable loading of firmware provided by .Xr ispfw 4 . +.It Va hint.isp. Ns Ar N Ns Va .fwload_force +A hint value to prefer firmware provided by +.Xr ispfw 4 , +even if it is older than the firmware in flash on the board. +If fwload_disable is also specified, fwload_force will be ignored. +.Pp +By default, with 27XX and newer controllers, the +.Xr isp 4 +driver will use the newer +firmware. +For older controllers, the +.Xr isp 4 +driver will use the firmware provided by +.Xr ispfw 4 +if it is available, and otherwise use the firmware in flash on the board. .It Va hint.isp. Ns Ar N Ns Va .ignore_nvram A hint value to ignore board NVRAM settings for. Otherwise use NVRAM settings. diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -457,7 +457,10 @@ if (IS_27XX(isp)) { switch (isp_load_risc(isp, 0)) { case ISP_ABORTED: - /* download ispfw(4) as it's newer than flash */ + /* + * download ispfw(4) as it's newer than flash, or + * the user requested it. + */ dodnld = 1; break; case ISP_SUCCESS: @@ -5222,7 +5225,20 @@ /* If ispfw(4) is loaded compare versions and use the newest */ if (isp->isp_osinfo.ispfw != NULL) { + int ispfw_newer = 0; + if (ISP_FW_NEWER_THANX(fcp->fw_ispfwrev, fcp->fw_flashrev)) { + ispfw_newer = 1; + } + + if (isp->isp_confopts & ISP_CFG_FWLOAD_FORCE) { + isp_prt(isp, ISP_LOGCONFIG, + "Loading RISC with %s ispfw(4) firmware %s", + (ispfw_newer == 0) ? "older" : "newer", + "because fwload_force is set"); + return (ISP_ABORTED); + } + if (ispfw_newer != 0) { isp_prt(isp, ISP_LOGCONFIG, "Loading RISC with newer ispfw(4) firmware"); return (ISP_ABORTED); diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c --- a/sys/dev/isp/isp_pci.c +++ b/sys/dev/isp/isp_pci.c @@ -291,6 +291,15 @@ isp->isp_confopts |= ISP_CFG_NORELOAD; } tval = 0; + if (resource_int_value(device_get_name(dev), device_get_unit(dev), "fwload_force", &tval) == 0 && tval != 0) { + isp->isp_confopts |= ISP_CFG_FWLOAD_FORCE; + } + if ((isp->isp_confopts & (ISP_CFG_NORELOAD|ISP_CFG_FWLOAD_FORCE)) == + (ISP_CFG_NORELOAD|ISP_CFG_FWLOAD_FORCE)) { + device_printf(dev, "WARNING: both fwload_disable and " + "fwload_force set, ispfw(4) loading disabled\n"); + } + tval = 0; if (resource_int_value(device_get_name(dev), device_get_unit(dev), "ignore_nvram", &tval) == 0 && tval != 0) { isp->isp_confopts |= ISP_CFG_NONVRAM; } diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h --- a/sys/dev/isp/ispvar.h +++ b/sys/dev/isp/ispvar.h @@ -612,6 +612,7 @@ #define ISP_CFG_16GB 0x8000 /* force 16Gb connection (26XX only) */ #define ISP_CFG_32GB 0x10000 /* force 32Gb connection (27XX only) */ #define ISP_CFG_64GB 0x20000 /* force 64Gb connection (28XX only) */ +#define ISP_CFG_FWLOAD_FORCE 0x40000 /* Prefer ispfw(4) even if older */ /* * For each channel, the outer layers should know what role that channel