NVIDIA патч для ядра 3.10.x
Материал из support.qbpro.ru
Версия от 02:34, 1 сентября 2013; imported>Vix (Новая страница: «==Патч== <nowiki> diff -ur -X - NVIDIA-Linux-x86_64-319.17-no-compat32.orig/kernel/nv-i2c.c NVIDIA-Linux-x86_64-319.17-no-compat32/kernel/nv-i2c.c …»)
Патч
diff -ur -X - NVIDIA-Linux-x86_64-319.17-no-compat32.orig/kernel/nv-i2c.c NVIDIA-Linux-x86_64-319.17-no-compat32/kernel/nv-i2c.c --- NVIDIA-Linux-x86_64-319.17-no-compat32.orig/kernel/nv-i2c.c 2013-04-26 00:22:30.000000000 -0400 +++ NVIDIA-Linux-x86_64-319.17-no-compat32/kernel/nv-i2c.c 2013-05-13 05:20:55.571981365 -0400 @@ -311,8 +311,6 @@ BOOL NV_API_CALL nv_i2c_del_adapter(nv_state_t *nv, void *data) { struct i2c_adapter *pI2cAdapter = (struct i2c_adapter *)data; - int osstatus = 0; - BOOL wasReleased = FALSE; #if defined(KERNEL_2_4) if (!NV_WEAK_SYMBOL_PRESENT(i2c_add_adapter)) @@ -324,15 +322,10 @@ if (!pI2cAdapter) return FALSE; // attempt release with the OS - osstatus = i2c_del_adapter(pI2cAdapter); + i2c_del_adapter(pI2cAdapter); + os_free_mem(pI2cAdapter); - if (!osstatus) - { - os_free_mem(pI2cAdapter); - wasReleased = TRUE; - } - - return wasReleased; + return TRUE; } #else // (defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)) diff -ur -X - NVIDIA-Linux-x86_64-319.17-no-compat32.orig/kernel/nv-procfs.c NVIDIA-Linux-x86_64-319.17-no-compat32/kernel/nv-procfs.c --- NVIDIA-Linux-x86_64-319.17-no-compat32.orig/kernel/nv-procfs.c 2013-04-26 00:22:30.000000000 -0400 +++ NVIDIA-Linux-x86_64-319.17-no-compat32/kernel/nv-procfs.c 2013-05-22 04:52:45.229495748 -0400 @@ -60,60 +60,41 @@ __entry; \ }) -#define NV_CREATE_PROC_FILE(name,parent,__read_proc, \ - __write_proc,__fops,__data) \ - ({ \ - struct proc_dir_entry *__entry; \ - int __mode = (S_IFREG | S_IRUGO); \ - if ((NvUPtr)(__write_proc) != 0) \ - __mode |= S_IWUSR; \ - __entry = NV_CREATE_PROC_ENTRY(name, __mode, parent); \ - if (__entry != NULL) \ - { \ - if ((NvUPtr)(__read_proc) != 0) \ - __entry->read_proc = (__read_proc); \ - if ((NvUPtr)(__write_proc) != 0) \ - { \ - __entry->write_proc = (__write_proc); \ - __entry->proc_fops = (__fops); \ - } \ - __entry->data = (__data); \ - } \ - __entry; \ - }) +#define NV_PROC_RW (S_IFREG|S_IRUGO|S_IWUSR) +#define NV_PROC_RO (S_IFREG|S_IRUGO) #define NV_CREATE_PROC_DIR(name,parent) \ ({ \ struct proc_dir_entry *__entry; \ int __mode = (S_IFDIR | S_IRUGO | S_IXUGO); \ - __entry = NV_CREATE_PROC_ENTRY(name, __mode, parent); \ + __entry = proc_mkdir_mode(name, __mode, parent); \ __entry; \ }) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,9,255) +static inline void *PDE_DATA(const struct inode *inode) { + return PDE(inode)->data; +} +#endif + #define NV_PROC_WRITE_BUFFER_SIZE (64 * RM_PAGE_SIZE) static int -nv_procfs_read_gpu_info( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data +nv_procfs_show_gpu_info( + struct seq_file *m, + void *v ) { - nv_state_t *nv = data; + nv_state_t *nv = m->private; nv_linux_state_t *nvl = NV_GET_NVL_FROM_NV_STATE(nv); struct pci_dev *dev = nvl->dev; char *type, *fmt, tmpstr[NV_DEVICE_NAME_LENGTH]; - int len = 0, status; + int status; NvU8 *uuid; NvU32 vbios_rev1, vbios_rev2, vbios_rev3, vbios_rev4, vbios_rev5; NvU32 fpga_rev1, fpga_rev2, fpga_rev3; nv_stack_t *sp = NULL; - *eof = 1; - NV_KMEM_CACHE_ALLOC_STACK(sp); if (sp == NULL) { @@ -134,31 +115,31 @@ if (rm_get_device_name(sp, nv, dev->device, dev->subsystem_vendor, dev->subsystem_device, NV_DEVICE_NAME_LENGTH, tmpstr) != RM_OK) - { + { strcpy (tmpstr, "Unknown"); } } - len += sprintf(page+len, "Model: \t\t %s\n", tmpstr); - len += sprintf(page+len, "IRQ: \t\t %d\n", nv->interrupt_line); + seq_printf(m, "Model: \t\t %s\n", tmpstr); + seq_printf(m, "IRQ: \t\t %d\n", nv->interrupt_line); if (NV_IS_GVI_DEVICE(nv)) { status = rm_gvi_get_firmware_version(sp, nv, &fpga_rev1, &fpga_rev2, &fpga_rev3); if (status != RM_OK) - len += sprintf(page+len, "Firmware: \t ????.??.??\n"); + seq_printf(m, "Firmware: \t ????.??.??\n"); else { fmt = "Firmware: \t %x.%x.%x\n"; - len += sprintf(page+len, fmt, fpga_rev1, fpga_rev2, fpga_rev3); + seq_printf(m, fmt, fpga_rev1, fpga_rev2, fpga_rev3); } } else { if (rm_get_gpu_uuid(sp, nv, &uuid, NULL) == RM_OK) { - len += sprintf(page+len, "GPU UUID: \t %s\n", (char *)uuid); + seq_printf(m, "GPU UUID: \t %s\n", (char *)uuid); os_free_mem(uuid); } @@ -166,12 +147,12 @@ &vbios_rev3, &vbios_rev4, &vbios_rev5) != RM_OK) { - len += sprintf(page+len, "Video BIOS: \t ??.??.??.??.??\n"); + seq_printf(m, "Video BIOS: \t ??.??.??.??.??\n"); } else { fmt = "Video BIOS: \t %02x.%02x.%02x.%02x.%02x\n"; - len += sprintf(page+len, fmt, vbios_rev1, vbios_rev2, vbios_rev3, + seq_printf(m, fmt, vbios_rev1, vbios_rev2, vbios_rev3, vbios_rev4, vbios_rev5); } } @@ -180,12 +161,12 @@ type = "PCI-E"; else type = "PCI"; - len += sprintf(page+len, "Bus Type: \t %s\n", type); + seq_printf(m, "Bus Type: \t %s\n", type); - len += sprintf(page+len, "DMA Size: \t %d bits\n", + seq_printf(m, "DMA Size: \t %d bits\n", nv_count_bits(dev->dma_mask)); - len += sprintf(page+len, "DMA Mask: \t 0x%llx\n", dev->dma_mask); - len += sprintf(page+len, "Bus Location: \t %04x:%02x.%02x.%x\n", + seq_printf(m, "DMA Mask: \t 0x%llx\n", dev->dma_mask); + seq_printf(m, "Bus Location: \t %04x:%02x.%02x.%x\n", nv->domain, nv->bus, nv->slot, PCI_FUNC(dev->devfn)); #if defined(DEBUG) do @@ -193,7 +174,7 @@ int j; for (j = 0; j < NV_GPU_NUM_BARS; j++) { - len += sprintf(page+len, "BAR%u: \t\t 0x%llx (%lluMB)\n", + seq_printf(m, "BAR%u: \t\t 0x%llx (%lluMB)\n", j, nv->bars[j].address, (nv->bars[j].size >> 20)); } } while (0); @@ -201,26 +182,120 @@ NV_KMEM_CACHE_FREE_STACK(sp); - return len; + return 0; } static int -nv_procfs_read_version( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data +nv_procfs_open_gpu_info( + struct inode *inode, + struct file *file +) +{ + return single_open(file, nv_procfs_show_gpu_info, PDE_DATA(inode)); +} + +static const struct file_operations nv_procfs_gpu_info_fops = { + .owner = THIS_MODULE, + .open = nv_procfs_open_gpu_info, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int +nv_procfs_show_version( + struct seq_file *m, + void *v +) +{ + seq_printf(m, "NVRM version: %s\n", pNVRM_ID); + seq_printf(m, "GCC version: %s\n", NV_COMPILER); + + return 0; +} + +static int +nv_procfs_open_version( + struct inode *inode, + struct file *file +) +{ + return single_open(file, nv_procfs_show_version, NULL); +} + +static const struct file_operations nv_procfs_version_fops = { + .owner = THIS_MODULE, + .open = nv_procfs_open_version, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int +nv_procfs_show_registry( + struct seq_file *m, + void *v +) +{ + nv_state_t *nv = m->private; + nv_linux_state_t *nvl = NULL; + char *registry_keys; + + if (nv != NULL) + nvl = NV_GET_NVL_FROM_NV_STATE(nv); + registry_keys = ((nvl != NULL) ? + nvl->registry_keys : nv_registry_keys); + + seq_printf(m, "Binary: \"%s\"\n", registry_keys); + + return 0; +} + +static ssize_t +nv_procfs_write_registry( + struct file *file, + const char __user *buffer, + size_t count, + loff_t *pos ) { - int len = 0; - *eof = 1; + int status = 0; + nv_file_private_t *nvfp = NV_GET_FILE_PRIVATE(file); + char *proc_buffer; + unsigned long bytes_left; + + down(&nvfp->fops_sp_lock[NV_FOPS_STACK_INDEX_PROCFS]); + + bytes_left = (NV_PROC_WRITE_BUFFER_SIZE - nvfp->off - 1); + + if (count == 0) + { + status = -EINVAL; + goto done; + } + else if ((bytes_left == 0) || (count > bytes_left)) + { + status = -ENOSPC; + goto done; + } + + proc_buffer = &((char *)nvfp->data)[nvfp->off]; + + if (copy_from_user(proc_buffer, buffer, count)) + { + nv_printf(NV_DBG_ERRORS, "NVRM: failed to copy in proc data!\n"); + status = -EFAULT; + } + else + { + nvfp->proc_data = PDE_DATA(file->f_inode); + nvfp->off += count; + } - len += sprintf(page+len, "NVRM version: %s\n", pNVRM_ID); - len += sprintf(page+len, "GCC version: %s\n", NV_COMPILER); +done: + up(&nvfp->fops_sp_lock[NV_FOPS_STACK_INDEX_PROCFS]); - return len; + return ((status < 0) ? status : count); } static int @@ -233,7 +308,7 @@ nv_stack_t *sp = NULL; if (0 == (file->f_mode & FMODE_WRITE)) - return 0; + return single_open(file, nv_procfs_show_registry, PDE_DATA(inode)); nvfp = nv_alloc_file_private(); if (nvfp == NULL) @@ -282,6 +357,9 @@ RM_STATUS rm_status; int rc = 0; + if (0 == (file->f_mode & FMODE_WRITE)) + return single_release(inode, file); + nvfp = NV_GET_FILE_PRIVATE(file); if (nvfp == NULL) return 0; @@ -346,122 +424,81 @@ return rc; } -static struct file_operations nv_procfs_registry_fops = { +static const struct file_operations nv_procfs_registry_fops = { .open = nv_procfs_open_registry, + .read = seq_read, + .llseek = seq_lseek, + .write = nv_procfs_write_registry, .release = nv_procfs_close_registry, }; static int -nv_procfs_read_params( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data +nv_procfs_show_params( + struct seq_file *m, + void *v ) { unsigned int i; - int len = 0; nv_parm_t *entry; - *eof = 1; for (i = 0; (entry = &nv_parms[i])->name != NULL; i++) - len += sprintf(page+len, "%s: %u\n", entry->name, *entry->data); + seq_printf(m, "%s: %u\n", entry->name, *entry->data); - len += sprintf(page+len, "RegistryDwords: \"%s\"\n", + seq_printf(m, "RegistryDwords: \"%s\"\n", (NVreg_RegistryDwords != NULL) ? NVreg_RegistryDwords : ""); - len += sprintf(page+len, "RmMsg: \"%s\"\n", + seq_printf(m, "RmMsg: \"%s\"\n", (NVreg_RmMsg != NULL) ? NVreg_RmMsg : ""); - return len; + return 0; } static int -nv_procfs_read_registry( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data -) +nv_procfs_open_params( + struct inode *inode, + struct file *file +) { - nv_state_t *nv = data; - nv_linux_state_t *nvl = NULL; - char *registry_keys; + return single_open(file, nv_procfs_show_params, NULL); +} - if (nv != NULL) - nvl = NV_GET_NVL_FROM_NV_STATE(nv); - registry_keys = ((nvl != NULL) ? - nvl->registry_keys : nv_registry_keys); +static const struct file_operations nv_procfs_params_fops = { + .owner = THIS_MODULE, + .open = nv_procfs_open_params, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; - *eof = 1; - return sprintf(page, "Binary: \"%s\"\n", registry_keys); -} static int -nv_procfs_write_registry( - struct file *file, - const char *buffer, - unsigned long count, - void *data +nv_procfs_show_text_file( + struct seq_file *m, + void *v ) { - int status = 0; - nv_file_private_t *nvfp = NV_GET_FILE_PRIVATE(file); - char *proc_buffer; - unsigned long bytes_left; - - down(&nvfp->fops_sp_lock[NV_FOPS_STACK_INDEX_PROCFS]); - - bytes_left = (NV_PROC_WRITE_BUFFER_SIZE - nvfp->off - 1); + seq_printf(m, "%s", (char *)m->private); - if (count == 0) - { - status = -EINVAL; - goto done; - } - else if ((bytes_left == 0) || (count > bytes_left)) - { - status = -ENOSPC; - goto done; - } - - proc_buffer = &((char *)nvfp->data)[nvfp->off]; - - if (copy_from_user(proc_buffer, buffer, count)) - { - nv_printf(NV_DBG_ERRORS, "NVRM: failed to copy in proc data!\n"); - status = -EFAULT; - } - else - { - nvfp->proc_data = data; - nvfp->off += count; - } - -done: - up(&nvfp->fops_sp_lock[NV_FOPS_STACK_INDEX_PROCFS]); - - return ((status < 0) ? status : (int)count); + return 0; } static int -nv_procfs_read_text_file( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data +nv_procfs_open_text_file( + struct inode *inode, + struct file *file ) { - *eof = 1; - return sprintf(page, "%s", (char *)data); + return single_open(file, nv_procfs_show_text_file, PDE_DATA(inode)); } +static const struct file_operations nv_procfs_text_fops = { + .owner = THIS_MODULE, + .open = nv_procfs_open_text_file, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static void nv_procfs_add_text_file( struct proc_dir_entry *parent, @@ -469,22 +506,7 @@ const char *text ) { - NV_CREATE_PROC_FILE(filename, parent, - nv_procfs_read_text_file, NULL, NULL, (void *)text); -} - -static void nv_procfs_unregister_all(struct proc_dir_entry *entry) -{ - while (entry) - { - struct proc_dir_entry *next = entry->next; - if (entry->subdir) - nv_procfs_unregister_all(entry->subdir); - remove_proc_entry(entry->name, entry->parent); - if (entry == proc_nvidia) - break; - entry = next; - } + proc_create_data(filename, NV_PROC_RO, parent, &nv_procfs_text_fops, (void *)text); } #endif @@ -513,26 +535,11 @@ if (!proc_nvidia) goto failed; - entry = NV_CREATE_PROC_FILE("params", proc_nvidia, - nv_procfs_read_params, NULL, NULL, NULL); + entry = proc_create("params", NV_PROC_RO, proc_nvidia, &nv_procfs_params_fops); if (!entry) goto failed; - /* - * entry->proc_fops originally points to a constant - * structure, so to add more methods for the - * binary registry write path, we need to replace the - * said entry->proc_fops with a new fops structure. - * However, in preparation for this, we need to preserve - * the procfs read() and write() operations. - */ - nv_procfs_registry_fops.read = entry->proc_fops->read; - nv_procfs_registry_fops.write = entry->proc_fops->write; - - entry = NV_CREATE_PROC_FILE("registry", proc_nvidia, - nv_procfs_read_registry, - nv_procfs_write_registry, - &nv_procfs_registry_fops, NULL); + entry = proc_create("registry", NV_PROC_RW, proc_nvidia, &nv_procfs_registry_fops); if (!entry) goto failed; @@ -553,8 +560,7 @@ nv_procfs_add_text_file(proc_nvidia_patches, "README", __README_patches); - entry = NV_CREATE_PROC_FILE("version", proc_nvidia, - nv_procfs_read_version, NULL, NULL, NULL); + entry = proc_create("version", NV_PROC_RO, proc_nvidia, &nv_procfs_version_fops); if (!entry) goto failed; @@ -571,15 +577,11 @@ if (!proc_nvidia_gpu) goto failed; - entry = NV_CREATE_PROC_FILE("information", proc_nvidia_gpu, - nv_procfs_read_gpu_info, NULL, NULL, nv); + entry = proc_create_data("information", NV_PROC_RO, proc_nvidia_gpu, &nv_procfs_gpu_info_fops, nv); if (!entry) goto failed; - entry = NV_CREATE_PROC_FILE("registry", proc_nvidia_gpu, - nv_procfs_read_registry, - nv_procfs_write_registry, - &nv_procfs_registry_fops, nv); + entry = proc_create_data("registry", NV_PROC_RW, proc_nvidia_gpu, &nv_procfs_registry_fops, nv); if (!entry) goto failed; } @@ -587,7 +589,7 @@ return 0; #if defined(CONFIG_PROC_FS) failed: - nv_procfs_unregister_all(proc_nvidia); + remove_proc_subtree("nvidia", proc_nvidia); return -1; #endif } @@ -595,6 +597,6 @@ void nv_unregister_procfs(void) { #if defined(CONFIG_PROC_FS) - nv_procfs_unregister_all(proc_nvidia); + remove_proc_subtree("nvidia", proc_nvidia); #endif }
Инструкция
#распаковываем проприетарный драйвер NVIDIA-Linux-x86_64-319.32.run -x сd ./NVIDIA-Linux-x86_64-319.32.run/kernel touch nv-i2c.c.patch #копируем в nv-i2c.c.patch текст патча #применяем патч patch -p1 <nv-i2c.c.patch #в случае если будут появляться вопросы о местоположении файлов, #просто указать их имя (скопировать из вопроса и вставить в командную строку)