Opis
W systemie operacyjnym Gentoo Linux dla karty graficznej GeForce GT 635M wymagane są starsze sterowniki “nvidia-drivers”, już niedostępne w publicznych ‘overlays’. Jednak te starsze sterowniki nie kompilują się w bieżącym kernelu Linux, dlatego utworzyłem ‘patch’ dostosowujący wersję “390.144-r2” sterowników. Plik z ‘patchem’ należy umieścić w folderze “files”, dopisać do listy w pliku “nvidia-drivers-390.144-r2.ebuild” i przebudować “manifest” pakietu.
Poza tym by skompilować “nvidia-drivers” w tej wersji potrzeba jeszcze na ten czas dopisać do linii “cmd_cc_o_c =” w pliku “/usr/src/linux/scripts/Makefile.build” przed “-c” następujący tekst: “-I/usr/src/linux/include/linux -I/usr/src/linux/fs/proc --include internal.h”. A z kernela potrzeba udostępnić “acpi_dev_for_each_child” i “acpi_bus_get_acpi_device” dla modułu “nvidia”.
‘Patch’
--- a/kernel/common/inc/nv-linux.h +++ b/kernel/common/inc/nv-linux.h @@ -340,7 +340,7 @@ #if defined(NV_PCI_DMA_MAPPING_ERROR_PRESENT) #if (NV_PCI_DMA_MAPPING_ERROR_ARGUMENT_COUNT == 2) #define NV_PCI_DMA_MAPPING_ERROR(dev, addr) \ - pci_dma_mapping_error(dev, addr) + dma_mapping_error(dev, addr) #elif (NV_PCI_DMA_MAPPING_ERROR_ARGUMENT_COUNT == 1) #define NV_PCI_DMA_MAPPING_ERROR(dev, addr) \ pci_dma_mapping_error(addr) --- a/kernel/nvidia-uvm/uvm8_gpu.c +++ b/kernel/nvidia-uvm/uvm8_gpu.c @@ -2214,15 +2214,15 @@ NV_STATUS uvm_gpu_map_cpu_pages(uvm_gpu_t *gpu, struct page *page, size_t size, NvU64 *dma_addr_out) { - NvU64 dma_addr = pci_map_page(gpu->pci_dev, page, 0, size, PCI_DMA_BIDIRECTIONAL); + NvU64 dma_addr = dma_map_page(&((struct pci_dev *)gpu->pci_dev)->dev, page, 0, size, DMA_BIDIRECTIONAL); UVM_ASSERT(PAGE_ALIGNED(size)); - if (NV_PCI_DMA_MAPPING_ERROR(gpu->pci_dev, dma_addr)) + if (NV_PCI_DMA_MAPPING_ERROR(&((struct pci_dev *)gpu->pci_dev)->dev, dma_addr)) return NV_ERR_OPERATING_SYSTEM; if (dma_addr < gpu->dma_addressable_start || dma_addr + size - 1 > gpu->dma_addressable_limit) { - pci_unmap_page(gpu->pci_dev, dma_addr, size, PCI_DMA_BIDIRECTIONAL); + dma_unmap_page(&((struct pci_dev *)gpu->pci_dev)->dev, dma_addr, size, DMA_BIDIRECTIONAL); UVM_ERR_PRINT_RL("PCI mapped range [0x%llx, 0x%llx) not in the addressable range [0x%llx, 0x%llx), GPU %s\n", dma_addr, dma_addr + (NvU64)size, @@ -2256,7 +2256,7 @@ if (gpu->npu_dev) dma_address = nv_expand_nvlink_addr(dma_address); dma_address += gpu->dma_addressable_start; - pci_unmap_page(gpu->pci_dev, dma_address, size, PCI_DMA_BIDIRECTIONAL); + dma_unmap_page(&((struct pci_dev *)gpu->pci_dev)->dev, dma_address, size, DMA_BIDIRECTIONAL); atomic64_sub(size, &gpu->mapped_cpu_pages_size); } --- a/kernel/nvidia-drm/nvidia-drm-gem.c +++ b/kernel/nvidia-drm/nvidia-drm-gem.c @@ -54,7 +54,7 @@ #if !defined(NV_DRM_DRIVER_HAS_GEM_PRIME_CALLBACKS) && \ defined(NV_DRM_GEM_OBJECT_VMAP_HAS_MAP_ARG) static int nv_drm_gem_vmap(struct drm_gem_object *gem, - struct dma_buf_map *map) + struct iosys_map *map) { map->vaddr = nv_drm_gem_prime_vmap(gem); if (map->vaddr == NULL) { @@ -65,7 +65,7 @@ } static void nv_drm_gem_vunmap(struct drm_gem_object *gem, - struct dma_buf_map *map) + struct iosys_map *map) { nv_drm_gem_prime_vunmap(gem, map->vaddr); map->vaddr = NULL; --- a/kernel/nvidia/nv-acpi.c +++ b/kernel/nvidia/nv-acpi.c @@ -590,7 +590,6 @@ { struct acpi_device *device = NULL; NV_STATUS rmStatus; - int retVal = -1; if (!handlesPresent) // Caller passed us invalid pointer. @@ -610,9 +609,9 @@ if (!nvif_parent_gpu_handle) /* unknown error */ break; - retVal = acpi_bus_get_device(nvif_parent_gpu_handle, &device); + device = acpi_bus_get_acpi_device(nvif_parent_gpu_handle); - if (ACPI_FAILURE(retVal) || !device) + if (!device) break; if (device->driver_data) @@ -684,7 +683,7 @@ if (nvif_parent_gpu_handle == NULL) return; - acpi_bus_get_device(nvif_parent_gpu_handle, &device); + device = acpi_bus_get_acpi_device(nvif_parent_gpu_handle); nv_uninstall_notifier(device, nv_acpi_event); nvif_parent_gpu_handle = NULL; @@ -1244,9 +1243,9 @@ if (!dev_handle) return NV_ERR_INVALID_ARGUMENT; - status = acpi_bus_get_device(dev_handle, &device); + device = acpi_bus_get_acpi_device(dev_handle); - if (ACPI_FAILURE(status) || !device) + if (!device) return NV_ERR_INVALID_ARGUMENT; if (!NV_MAY_SLEEP()) --- a/kernel/nvidia/nv-dma.c +++ b/kernel/nvidia/nv-dma.c @@ -27,9 +27,9 @@ NvU64 *va ) { - *va = pci_map_page(dma_map->dev, dma_map->pages[0], 0, - dma_map->page_count * PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (NV_PCI_DMA_MAPPING_ERROR(dma_map->dev, *va)) + *va = dma_map_page(&((struct pci_dev *)dma_map->dev)->dev, dma_map->pages[0], 0, + dma_map->page_count * PAGE_SIZE, DMA_BIDIRECTIONAL); + if (NV_PCI_DMA_MAPPING_ERROR(&((struct pci_dev *)dma_map->dev)->dev, *va)) { return NV_ERR_OPERATING_SYSTEM; } @@ -57,8 +57,8 @@ static void nv_dma_unmap_contig(nv_dma_map_t *dma_map) { - pci_unmap_page(dma_map->dev, dma_map->mapping.contig.dma_addr, - dma_map->page_count * PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + dma_unmap_page(&((struct pci_dev *)dma_map->dev)->dev, dma_map->mapping.contig.dma_addr, + dma_map->page_count * PAGE_SIZE, DMA_BIDIRECTIONAL); } static void nv_fill_scatterlist @@ -166,10 +166,10 @@ NV_FOR_EACH_DMA_SUBMAP(dma_map, submap, i) { - submap->sg_map_count = pci_map_sg(dma_map->dev, + submap->sg_map_count = dma_map_sg(&((struct pci_dev *)dma_map->dev)->dev, NV_DMA_SUBMAP_SCATTERLIST(submap), NV_DMA_SUBMAP_SCATTERLIST_LENGTH(submap), - PCI_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); if (submap->sg_map_count == 0) { status = NV_ERR_OPERATING_SYSTEM; @@ -197,9 +197,9 @@ break; } - pci_unmap_sg(dma_map->dev, NV_DMA_SUBMAP_SCATTERLIST(submap), + dma_unmap_sg(&((struct pci_dev *)dma_map->dev)->dev, NV_DMA_SUBMAP_SCATTERLIST(submap), NV_DMA_SUBMAP_SCATTERLIST_LENGTH(submap), - PCI_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); } } --- a/kernel/nvidia/nv.c +++ b/kernel/nvidia/nv.c @@ -2742,7 +2742,7 @@ if (!nvl->tce_bypass_enabled) { NvU64 new_mask = (((NvU64)1) << phys_addr_bits) - 1; - pci_set_dma_mask(nvl->dev, new_mask); + dma_set_mask(&((struct pci_dev *)nvl->dev)->dev, new_mask); } } --- a/kernel/nvidia-drm/nvidia-dma-resv-helper.h +++ b/kernel/nvidia-drm/nvidia-dma-resv-helper.h @@ -69,7 +69,7 @@ nv_dma_fence_t *fence) { #if defined(NV_LINUX_DMA_RESV_H_PRESENT) - dma_resv_add_excl_fence(obj, fence); + dma_resv_add_fence(obj, fence, DMA_RESV_USAGE_WRITE); #else reservation_object_add_excl_fence(obj, fence); #endif --- a/kernel/nvidia-drm/nvidia-drm-helper.c +++ b/kernel/nvidia-drm/nvidia-drm-helper.c @@ -39,6 +39,8 @@ #include <drm/drm_atomic_uapi.h> #endif +#include <drm/drm_framebuffer.h> + static void __nv_drm_framebuffer_put(struct drm_framebuffer *fb) { #if defined(NV_DRM_FRAMEBUFFER_GET_PRESENT) --- a/kernel/nvidia/nv-acpi.c +++ b/kernel/nvidia/nv-acpi.c @@ -215,6 +215,24 @@ return 0; } +LIST_HEAD( acpi_children ); + +struct acpi_child +{ struct list_head node; + struct acpi_device data; +}; + +static +int +acpi_add_child( struct acpi_device *dev +, void *data +){ struct acpi_child *node = kmalloc( sizeof( struct acpi_child ), GFP_KERNEL ); + node->data = *dev; + INIT_LIST_HEAD( &node->node ); + list_add_tail( &node->node, &acpi_children ); + return 0; +} + static int nv_acpi_add(struct acpi_device *device) { /* @@ -230,6 +248,7 @@ struct list_head *node, *next; nv_acpi_integer_t device_id = 0; int device_counter = 0; + struct acpi_child *entry, *temp; status = nv_kmem_cache_alloc_stack(&sp); if (status != 0) @@ -256,10 +275,11 @@ // grab handles to all the important nodes representing devices - list_for_each_safe(node, next, &device->children) + acpi_dev_for_each_child( device, acpi_add_child, 0 ); + list_for_each_safe(node, next, &acpi_children) { struct acpi_device *dev = - list_entry(node, struct acpi_device, node); + &list_entry(node, struct acpi_child, node)->data; if (!dev) continue; @@ -297,6 +317,11 @@ device_counter++; } + list_for_each_entry_safe( entry, temp, &acpi_children, node ) + { list_del( &entry->node ); + kfree(entry); + } + // arg 0, bits 1:0, 0 = enable events control_argument_0.integer.type = ACPI_TYPE_INTEGER; @@ -1236,6 +1261,7 @@ NvU32 i; acpi_handle dev_handle = NULL; acpi_handle lcd_dev_handle = NULL; + struct acpi_child *entry, *temp; if (!nv_acpi_get_device_handle(nv, &dev_handle)) return NV_ERR_NOT_SUPPORTED; @@ -1258,10 +1284,11 @@ return NV_ERR_NOT_SUPPORTED; } - list_for_each_safe(node, next, &device->children) + acpi_dev_for_each_child( device, acpi_add_child, 0 ); + list_for_each_safe(node, next, &acpi_children) { struct acpi_device *dev = - list_entry(node, struct acpi_device, node); + &list_entry(node, struct acpi_child, node)->data; if (!dev) continue; @@ -1281,6 +1308,10 @@ } } + list_for_each_entry_safe( entry, temp, &acpi_children, node ) + { list_del( &entry->node ); + kfree(entry); + } if (lcd_dev_handle == NULL) { --- a/kernel/nvidia-drm/nvidia-drm-connector.c +++ b/kernel/nvidia-drm/nvidia-drm-connector.c @@ -98,7 +98,7 @@ break; } - if (connector->override_edid) { + if (connector->edid_override) { const struct drm_property_blob *edid = connector->edid_blob_ptr; if (edid->length <= sizeof(pDetectParams->edid.buffer)) { --- a/kernel/nvidia-drm/nvidia-drm-drv.c ...skipping... const struct drm_property_blob *edid = connector->edid_blob_ptr; if (edid->length <= sizeof(pDetectParams->edid.buffer)) { --- a/kernel/nvidia-drm/nvidia-drm-drv.c +++ b/kernel/nvidia-drm/nvidia-drm-drv.c @@ -242,7 +242,7 @@ /* Currently unused. Update when needed. */ - dev->mode_config.fb_base = 0; + //dev->mode_config.fb_base = 0; dev->mode_config.async_page_flip = false; --- a/kernel/nvidia/nv-acpi.c +++ b/kernel/nvidia/nv-acpi.c @@ -24,7 +24,7 @@ static int nv_acpi_add (struct acpi_device *); #if !defined(NV_ACPI_DEVICE_OPS_REMOVE_ARGUMENT_COUNT) || (NV_ACPI_DEVICE_OPS_REMOVE_ARGUMENT_COUNT == 2) -static int nv_acpi_remove_two_args(struct acpi_device *device, int type); +static void nv_acpi_remove_two_args(struct acpi_device *device); #else static int nv_acpi_remove_one_arg(struct acpi_device *device); #endif @@ -358,7 +358,7 @@ } #if !defined(NV_ACPI_DEVICE_OPS_REMOVE_ARGUMENT_COUNT) || (NV_ACPI_DEVICE_OPS_REMOVE_ARGUMENT_COUNT == 2) -static int nv_acpi_remove_two_args(struct acpi_device *device, int type) +static void nv_acpi_remove_two_args(struct acpi_device *device) #else static int nv_acpi_remove_one_arg(struct acpi_device *device) #endif @@ -410,8 +410,6 @@ module_put(THIS_MODULE); device->driver_data = NULL; } - - return status; } static void nv_acpi_event(acpi_handle handle, u32 event_type, void *data)