Module Name: src Committed By: snj Date: Thu Jul 30 15:46:41 UTC 2015
Modified Files: src/sys/external/bsd/drm2/dist/drm/radeon [netbsd-7]: radeon_bios.c src/sys/external/bsd/drm2/include/linux [netbsd-7]: pci.h Log Message: Pull up following revision(s) (requested by riastradh in ticket #906): sys/external/bsd/drm2/include/linux/pci.h: revisions 1.18, 1.19 sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c: revision 1.4 Save the location of the found ROM so caller can bus_space_read it. -- Use bus_space_read rather than kmemdup to read ROM. jakllsch@ reports that on some 64-bit systems, kmemdup does 8-byte reads, which yield garbage in the high word. bus_space_read_region_1 does 1-byte reads instead, which seem to work. Derived from a patch from jakllsch@. -- Fix type of pd_rom_found_size: it's a size, not a handle. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.2.4.1 \ src/sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c cvs rdiff -u -r1.7.2.6 -r1.7.2.7 \ src/sys/external/bsd/drm2/include/linux/pci.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c diff -u src/sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c:1.2 src/sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c:1.2.4.1 --- src/sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c:1.2 Wed Jul 16 20:59:57 2014 +++ src/sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c Thu Jul 30 15:46:41 2015 @@ -116,6 +116,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 +150,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: src/sys/external/bsd/drm2/include/linux/pci.h diff -u src/sys/external/bsd/drm2/include/linux/pci.h:1.7.2.6 src/sys/external/bsd/drm2/include/linux/pci.h:1.7.2.7 --- src/sys/external/bsd/drm2/include/linux/pci.h:1.7.2.6 Thu Apr 23 07:31:17 2015 +++ src/sys/external/bsd/drm2/include/linux/pci.h Thu Jul 30 15:46:41 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: pci.h,v 1.7.2.6 2015/04/23 07:31:17 snj Exp $ */ +/* $NetBSD: pci.h,v 1.7.2.7 2015/07/30 15:46:41 snj Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -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_size_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; }