From edcd0b947520d1a04cfb598eaad271f40856dd65 Mon Sep 17 00:00:00 2001 From: xdave Date: Tue, 6 Aug 2013 17:41:19 -0600 Subject: [PATCH] nvidia304: add patch to make this work on Linux 3.10. --- .../files/nvidia_304.88_linux_3.10.patch | 653 ++++++++++++++++++ srcpkgs/nvidia304/template | 7 +- 2 files changed, 659 insertions(+), 1 deletion(-) create mode 100644 srcpkgs/nvidia304/files/nvidia_304.88_linux_3.10.patch diff --git a/srcpkgs/nvidia304/files/nvidia_304.88_linux_3.10.patch b/srcpkgs/nvidia304/files/nvidia_304.88_linux_3.10.patch new file mode 100644 index 00000000000..f944035cd7e --- /dev/null +++ b/srcpkgs/nvidia304/files/nvidia_304.88_linux_3.10.patch @@ -0,0 +1,653 @@ +diff -urN NVIDIA-Linux-x86_64-304.88/kernel/nv-i2c.c NVIDIA-Linux-x86_64-304.88.new/kernel/nv-i2c.c +--- NVIDIA-Linux-x86_64-304.88/kernel/nv-i2c.c 2013-03-27 17:26:51.000000000 -0400 ++++ NVIDIA-Linux-x86_64-304.88.new/kernel/nv-i2c.c 2013-07-05 10:04:23.000000000 -0400 +@@ -1,3 +1,4 @@ ++ + /* _NVRM_COPYRIGHT_BEGIN_ + * + * Copyright 2005-2011 by NVIDIA Corporation. All rights reserved. All +@@ -311,8 +312,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 +323,10 @@ + if (!pI2cAdapter) return FALSE; + + // attempt release with the OS +- osstatus = i2c_del_adapter(pI2cAdapter); +- +- if (!osstatus) +- { +- os_free_mem(pI2cAdapter); +- wasReleased = TRUE; +- } ++ i2c_del_adapter(pI2cAdapter); ++ os_free_mem(pI2cAdapter); + +- return wasReleased; ++ return TRUE; + } + + #else // (defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)) +diff -urN NVIDIA-Linux-x86_64-304.88/kernel/nv-procfs.c NVIDIA-Linux-x86_64-304.88.new/kernel/nv-procfs.c +--- NVIDIA-Linux-x86_64-304.88/kernel/nv-procfs.c 2013-03-27 17:26:51.000000000 -0400 ++++ NVIDIA-Linux-x86_64-304.88.new/kernel/nv-procfs.c 2013-07-05 10:12:52.000000000 -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); + } + } +@@ -182,12 +163,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 +@@ -195,7 +176,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); +@@ -203,26 +184,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 + ) + { +- int len = 0; +- *eof = 1; ++ return single_open(file, nv_procfs_show_gpu_info, PDE_DATA(inode)); ++} + +- len += sprintf(page+len, "NVRM version: %s\n", pNVRM_ID); +- len += sprintf(page+len, "GCC version: %s\n", NV_COMPILER); ++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, ++}; + +- return len; ++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 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; ++ } ++ ++done: ++ up(&nvfp->fops_sp_lock[NV_FOPS_STACK_INDEX_PROCFS]); ++ ++ return ((status < 0) ? status : count); + } + + static struct pci_dev *nv_get_agp_device_by_class(unsigned int class) +@@ -432,7 +507,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) +@@ -481,6 +556,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; +@@ -545,122 +623,84 @@ + 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; +- +- if (nv != NULL) +- nvl = NV_GET_NVL_FROM_NV_STATE(nv); +- registry_keys = ((nvl != NULL) ? +- nvl->registry_keys : nv_registry_keys); + +- *eof = 1; +- return sprintf(page, "Binary: \"%s\"\n", registry_keys); ++return single_open(file, nv_procfs_show_params, NULL); + } ++ ++ ++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, ++}; ++ + + 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; ++ seq_printf(m, "%s", (char *)m->private); + +- 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 = 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, +@@ -668,22 +708,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 + +@@ -713,26 +738,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; + +@@ -753,8 +763,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; + +@@ -771,15 +780,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; + +@@ -788,28 +793,34 @@ + proc_nvidia_agp = NV_CREATE_PROC_DIR("agp", proc_nvidia); + if (!proc_nvidia_agp) + goto failed; +- +- entry = NV_CREATE_PROC_FILE("status", proc_nvidia_agp, +- nv_procfs_read_agp_status, NULL, NULL, nv); +- if (!entry) +- goto failed; +- +- entry = NV_CREATE_PROC_FILE("host-bridge", proc_nvidia_agp, +- nv_procfs_read_agp_info, NULL, NULL, NULL); +- if (!entry) +- goto failed; +- +- entry = NV_CREATE_PROC_FILE("gpu", proc_nvidia_agp, +- nv_procfs_read_agp_info, NULL, NULL, nv); +- if (!entry) +- 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); ++ ++ // entry = NV_CREATE_PROC_FILE("status", proc_nvidia_agp, ++ // nv_procfs_read_agp_status, NULL, NULL, nv); ++// entry = proc_create("status", NV_PROC_RO, proc_nvidia, &nv_procfs_params_fops); ++ ++ // if (!entry) ++ // goto failed; ++ ++ // entry = NV_CREATE_PROC_FILE("host-bridge", proc_nvidia_agp, ++ // nv_procfs_read_agp_info, NULL, NULL, NULL); ++ // if (!entry) ++ // goto failed; ++ ++ //entry = NV_CREATE_PROC_FILE("gpu", proc_nvidia_agp, ++ // nv_procfs_read_agp_info, NULL, NULL, nv); ++ //if (!entry) ++ // goto failed; + } + } + #endif + return 0; + #if defined(CONFIG_PROC_FS) + failed: +- nv_procfs_unregister_all(proc_nvidia); ++ remove_proc_subtree("nvidia", proc_nvidia); + return -1; + #endif + } +@@ -817,6 +828,6 @@ + void nv_unregister_procfs(void) + { + #if defined(CONFIG_PROC_FS) +- nv_procfs_unregister_all(proc_nvidia); ++ remove_proc_subtree("nvidia", proc_nvidia); + #endif + } diff --git a/srcpkgs/nvidia304/template b/srcpkgs/nvidia304/template index 91903374cfc..546d995228b 100644 --- a/srcpkgs/nvidia304/template +++ b/srcpkgs/nvidia304/template @@ -1,7 +1,7 @@ # Template file for 'nvidia304' pkgname=nvidia304 version=304.88 -revision=1 +revision=2 short_desc="NVIDIA drivers for linux (304.xx series)" maintainer="Juan RP " license="Propietary NVIDIA license" @@ -26,6 +26,11 @@ do_extract() { cd ${wrksrc} ./${_pkg}.run --extract-only rm -f ${_pkg}.run + # Had trouble getting this patch to work the normal way because + # the source directory is named arch-specific -- Dave. + msg_normal "* Applying patch nvidia_304.88_linux_3.10.patch ...\n" + patch -sl -Np1 -d ${_pkg} -i \ + "${FILESDIR}/nvidia_304.88_linux_3.10.patch" } do_install() {