Use PCI ROM MD fallback if PCI ROM BAR points to invalid ROM.

We previously applied the PCI ROM MD fallback only if the PCI ROM BAR
was altogether unpopulated.  Some Radeon devices seem to have a
populated PCI ROM BAR pointing at a bogus ROM, while 0xc0000 works
fine.

Fixes at least one manifestation of PR kern/49964.
This commit is contained in:
riastradh 2016-01-17 01:40:39 +00:00
parent 6510a8eabd
commit bb8ee6680c
1 changed files with 22 additions and 5 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pci.h,v 1.21 2015/10/27 13:21:18 riastradh Exp $ */
/* $NetBSD: pci.h,v 1.22 2016/01/17 01:40:39 riastradh Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@ -491,6 +491,7 @@ pci_map_rom_md(struct pci_dev *pdev)
pdev->pd_rom_bst = pdev->pd_pa.pa_memt;
pdev->pd_rom_bsh = rom_bsh;
pdev->pd_rom_size = rom_size;
pdev->pd_kludges |= NBPCI_KLUDGE_MAP_ROM;
return 0;
#else
@ -507,9 +508,8 @@ pci_map_rom(struct pci_dev *pdev, size_t *sizep)
if (pci_mapreg_map(&pdev->pd_pa, PCI_MAPREG_ROM, PCI_MAPREG_TYPE_ROM,
(BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR),
&pdev->pd_rom_bst, &pdev->pd_rom_bsh, NULL, &pdev->pd_rom_size)
!= 0 &&
pci_map_rom_md(pdev) != 0)
return NULL;
!= 0)
goto fail_mi;
pdev->pd_kludges |= NBPCI_KLUDGE_MAP_ROM;
/* XXX This type is obviously wrong in general... */
@ -517,14 +517,31 @@ pci_map_rom(struct pci_dev *pdev, size_t *sizep)
pdev->pd_rom_size, PCI_ROM_CODE_TYPE_X86,
&pdev->pd_rom_found_bsh, &pdev->pd_rom_found_size)) {
pci_unmap_rom(pdev, NULL);
return NULL;
goto fail_mi;
}
goto success;
fail_mi:
if (pci_map_rom_md(pdev) != 0)
goto fail_md;
/* XXX This type is obviously wrong in general... */
if (pci_find_rom(&pdev->pd_pa, pdev->pd_rom_bst, pdev->pd_rom_bsh,
pdev->pd_rom_size, PCI_ROM_CODE_TYPE_X86,
&pdev->pd_rom_found_bsh, &pdev->pd_rom_found_size)) {
pci_unmap_rom(pdev, NULL);
goto fail_md;
}
success:
KASSERT(pdev->pd_rom_found_size <= SIZE_T_MAX);
*sizep = pdev->pd_rom_found_size;
pdev->pd_rom_vaddr = bus_space_vaddr(pdev->pd_rom_bst,
pdev->pd_rom_found_bsh);
return pdev->pd_rom_vaddr;
fail_md:
return NULL;
}
static inline void __pci_rom_iomem *