Skip to content

Commit c82cacd

Browse files
tiwaigregkh
authored andcommitted
usb: renesas-xhci: Prefer firmware loading on unknown ROM state
The recent attempt to handle an unknown ROM state in the commit d143825 ("usb: renesas-xhci: Fix handling of unknown ROM state") resulted in a regression and reverted later by the commit 44cf536 ("Revert "usb: renesas-xhci: Fix handling of unknown ROM state""). The problem of the former fix was that it treated the failure of firmware loading as a fatal error. Since the firmware files aren't included in the standard linux-firmware tree, most users don't have them, hence they got the non-working system after that. The revert fixed the regression, but also it didn't make the firmware loading triggered even on the devices that do need it. So we need still a fix for them. This is another attempt to handle the unknown ROM state. Like the previous fix, this also tries to load the firmware when ROM shows unknown state. In this patch, however, the failure of a firmware loading (such as a missing firmware file) isn't handled as a fatal error any longer when ROM has been already detected, but it falls back to the ROM mode like before. The error is returned only when no ROM is detected and the firmware loading failed. Along with it, for simplifying the code flow, the detection and the check of ROM is factored out from renesas_fw_check_running() and done in the caller side, renesas_xhci_check_request_fw(). It avoids the redundant ROM checks. The patch was tested on Lenovo Thinkpad T14 gen (BIOS 1.34). Also it was confirmed that no regression is seen on another Thinkpad T14 machine that has worked without the patch, too. Fixes: 44cf536 ("Revert "usb: renesas-xhci: Fix handling of unknown ROM state"") Cc: stable <[email protected]> Signed-off-by: Takashi Iwai <[email protected]> BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1189207 Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 4a1e25c commit c82cacd

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

drivers/usb/host/xhci-pci-renesas.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,8 @@ static int renesas_check_rom_state(struct pci_dev *pdev)
207207
return 0;
208208

209209
case RENESAS_ROM_STATUS_NO_RESULT: /* No result yet */
210-
return 0;
210+
dev_dbg(&pdev->dev, "Unknown ROM status ...\n");
211+
return -ENOENT;
211212

212213
case RENESAS_ROM_STATUS_ERROR: /* Error State */
213214
default: /* All other states are marked as "Reserved states" */
@@ -224,14 +225,6 @@ static int renesas_fw_check_running(struct pci_dev *pdev)
224225
u8 fw_state;
225226
int err;
226227

227-
/* Check if device has ROM and loaded, if so skip everything */
228-
err = renesas_check_rom(pdev);
229-
if (err) { /* we have rom */
230-
err = renesas_check_rom_state(pdev);
231-
if (!err)
232-
return err;
233-
}
234-
235228
/*
236229
* Test if the device is actually needing the firmware. As most
237230
* BIOSes will initialize the device for us. If the device is
@@ -591,21 +584,39 @@ int renesas_xhci_check_request_fw(struct pci_dev *pdev,
591584
(struct xhci_driver_data *)id->driver_data;
592585
const char *fw_name = driver_data->firmware;
593586
const struct firmware *fw;
587+
bool has_rom;
594588
int err;
595589

590+
/* Check if device has ROM and loaded, if so skip everything */
591+
has_rom = renesas_check_rom(pdev);
592+
if (has_rom) {
593+
err = renesas_check_rom_state(pdev);
594+
if (!err)
595+
return 0;
596+
else if (err != -ENOENT)
597+
has_rom = false;
598+
}
599+
596600
err = renesas_fw_check_running(pdev);
597601
/* Continue ahead, if the firmware is already running. */
598602
if (err == 0)
599603
return 0;
600604

605+
/* no firmware interface available */
601606
if (err != 1)
602-
return err;
607+
return has_rom ? 0 : err;
603608

604609
pci_dev_get(pdev);
605-
err = request_firmware(&fw, fw_name, &pdev->dev);
610+
err = firmware_request_nowarn(&fw, fw_name, &pdev->dev);
606611
pci_dev_put(pdev);
607612
if (err) {
608-
dev_err(&pdev->dev, "request_firmware failed: %d\n", err);
613+
if (has_rom) {
614+
dev_info(&pdev->dev, "failed to load firmware %s, fallback to ROM\n",
615+
fw_name);
616+
return 0;
617+
}
618+
dev_err(&pdev->dev, "failed to load firmware %s: %d\n",
619+
fw_name, err);
609620
return err;
610621
}
611622

0 commit comments

Comments
 (0)