Index: sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c =================================================================== RCS file: /cvsroot/src/sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c,v retrieving revision 1.3 diff -p -u -r1.3 radeon_bios.c --- sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c 13 Jun 2015 18:18:18 -0000 1.3 +++ sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c 22 Jun 2015 21:45:34 -0000 @@ -116,6 +124,31 @@ static bool radeon_read_bios(struct rade return false; } +#ifdef __NetBSD__ + /* + * Using kmemdup results in >4-byte memory access on 64-bit + * systems, which yields bogus answers on some devices. So we + * use bus_space(9) to do guaranteed byte access with + * bus_space_read_region_1 which seems to work better. + */ + { + const bus_space_tag_t bst = rdev->pdev->pd_rom_bst; + const bus_space_handle_t bsh = rdev->pdev->pd_rom_found_bsh; + + if (size == 0 || + bus_space_read_1(bst, bsh, 0) != 0x55 || + bus_space_read_1(bst, bsh, 1) != 0xaa) { + pci_unmap_rom(rdev->pdev, bios); + return false; + } + rdev->bios = kmalloc(size, GFP_KERNEL); + if (rdev->bios == NULL) { + pci_unmap_rom(rdev->pdev, bios); + return false; + } + bus_space_read_region_1(bst, bsh, 0, rdev->bios, size); + } +#else if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { pci_unmap_rom(rdev->pdev, bios); return false; @@ -125,6 +158,7 @@ static bool radeon_read_bios(struct rade pci_unmap_rom(rdev->pdev, bios); return false; } +#endif pci_unmap_rom(rdev->pdev, bios); return true; } Index: sys/external/bsd/drm2/include/linux/pci.h =================================================================== RCS file: /cvsroot/src/sys/external/bsd/drm2/include/linux/pci.h,v retrieving revision 1.17 diff -p -u -r1.17 pci.h --- sys/external/bsd/drm2/include/linux/pci.h 6 Apr 2015 02:29:18 -0000 1.17 +++ sys/external/bsd/drm2/include/linux/pci.h 22 Jun 2015 21:45:34 -0000 @@ -126,6 +126,8 @@ struct pci_dev { bus_space_tag_t pd_rom_bst; bus_space_handle_t pd_rom_bsh; bus_size_t pd_rom_size; + bus_space_handle_t pd_rom_found_bsh; + bus_space_handle_t pd_rom_found_size; void *pd_rom_vaddr; device_t pd_dev; struct drm_device *pd_drm_dev; /* XXX Nouveau kludge! */ @@ -504,8 +506,6 @@ pci_map_rom_md(struct pci_dev *pdev) static inline void __pci_rom_iomem * pci_map_rom(struct pci_dev *pdev, size_t *sizep) { - bus_space_handle_t bsh; - bus_size_t size; KASSERT(!ISSET(pdev->pd_kludges, NBPCI_KLUDGE_MAP_ROM)); @@ -519,14 +519,16 @@ pci_map_rom(struct pci_dev *pdev, size_t /* 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, &bsh, &size)) { + 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; } - KASSERT(size <= SIZE_T_MAX); - *sizep = size; - pdev->pd_rom_vaddr = bus_space_vaddr(pdev->pd_rom_bst, bsh); + 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; }