| /* |
| * Copyright (c) 2013 Luis R. Rodriguez <mcgrof@do-not-panic.com> |
| * |
| * Linux backport symbols for kernels 3.10. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| */ |
| |
| #include <linux/kernel.h> |
| #include <linux/module.h> |
| #include <linux/err.h> |
| #include <linux/proc_fs.h> |
| #include <linux/random.h> |
| #include <linux/tty.h> |
| #include <linux/pci.h> |
| #include <linux/pci_regs.h> |
| #include <linux/of.h> |
| #include <linux/mm.h> |
| |
| void proc_set_size(struct proc_dir_entry *de, loff_t size) |
| { |
| de->size = size; |
| } |
| EXPORT_SYMBOL_GPL(proc_set_size); |
| |
| void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid) |
| { |
| de->uid = uid; |
| de->gid = gid; |
| } |
| EXPORT_SYMBOL_GPL(proc_set_user); |
| |
| /* get_random_int() was not exported for module use until 3.10-rc. |
| Implement it here in terms of the more expensive get_random_bytes() |
| */ |
| unsigned int get_random_int(void) |
| { |
| unsigned int r; |
| get_random_bytes(&r, sizeof(r)); |
| |
| return r; |
| } |
| EXPORT_SYMBOL_GPL(get_random_int); |
| |
| #ifdef CONFIG_TTY |
| /** |
| * tty_port_tty_wakeup - helper to wake up a tty |
| * |
| * @port: tty port |
| */ |
| void tty_port_tty_wakeup(struct tty_port *port) |
| { |
| struct tty_struct *tty = tty_port_tty_get(port); |
| |
| if (tty) { |
| tty_wakeup(tty); |
| tty_kref_put(tty); |
| } |
| } |
| EXPORT_SYMBOL_GPL(tty_port_tty_wakeup); |
| |
| /** |
| * tty_port_tty_hangup - helper to hang up a tty |
| * |
| * @port: tty port |
| * @check_clocal: hang only ttys with CLOCAL unset? |
| */ |
| void tty_port_tty_hangup(struct tty_port *port, bool check_clocal) |
| { |
| struct tty_struct *tty = tty_port_tty_get(port); |
| |
| if (tty && (!check_clocal || !C_CLOCAL(tty))) |
| tty_hangup(tty); |
| tty_kref_put(tty); |
| } |
| EXPORT_SYMBOL_GPL(tty_port_tty_hangup); |
| #endif /* CONFIG_TTY */ |
| |
| #ifdef CONFIG_PCI_IOV |
| /* |
| * pci_vfs_assigned - returns number of VFs are assigned to a guest |
| * @dev: the PCI device |
| * |
| * Returns number of VFs belonging to this device that are assigned to a guest. |
| * If device is not a physical function returns -ENODEV. |
| */ |
| int pci_vfs_assigned(struct pci_dev *dev) |
| { |
| struct pci_dev *vfdev; |
| unsigned int vfs_assigned = 0; |
| unsigned short dev_id; |
| |
| /* only search if we are a PF */ |
| if (!dev->is_physfn) |
| return 0; |
| |
| /* |
| * determine the device ID for the VFs, the vendor ID will be the |
| * same as the PF so there is no need to check for that one |
| */ |
| pci_read_config_word(dev, dev->sriov->pos + PCI_SRIOV_VF_DID, &dev_id); |
| |
| /* loop through all the VFs to see if we own any that are assigned */ |
| vfdev = pci_get_device(dev->vendor, dev_id, NULL); |
| while (vfdev) { |
| /* |
| * It is considered assigned if it is a virtual function with |
| * our dev as the physical function and the assigned bit is set |
| */ |
| if (vfdev->is_virtfn && (vfdev->physfn == dev) && |
| (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)) |
| vfs_assigned++; |
| |
| vfdev = pci_get_device(dev->vendor, dev_id, vfdev); |
| } |
| |
| return vfs_assigned; |
| } |
| EXPORT_SYMBOL_GPL(pci_vfs_assigned); |
| #endif /* CONFIG_PCI_IOV */ |
| |
| #ifdef CONFIG_OF |
| /** |
| * of_property_read_u32_index - Find and read a u32 from a multi-value property. |
| * |
| * @np: device node from which the property value is to be read. |
| * @propname: name of the property to be searched. |
| * @index: index of the u32 in the list of values |
| * @out_value: pointer to return value, modified only if no error. |
| * |
| * Search for a property in a device node and read nth 32-bit value from |
| * it. Returns 0 on success, -EINVAL if the property does not exist, |
| * -ENODATA if property does not have a value, and -EOVERFLOW if the |
| * property data isn't large enough. |
| * |
| * The out_value is modified only if a valid u32 value can be decoded. |
| */ |
| int of_property_read_u32_index(const struct device_node *np, |
| const char *propname, |
| u32 index, u32 *out_value) |
| { |
| const u32 *val = of_find_property_value_of_size(np, propname, |
| ((index + 1) * sizeof(*out_value))); |
| |
| if (IS_ERR(val)) |
| return PTR_ERR(val); |
| |
| *out_value = be32_to_cpup(((__be32 *)val) + index); |
| return 0; |
| } |
| EXPORT_SYMBOL_GPL(of_property_read_u32_index); |
| #endif /* CONFIG_OF */ |
| |
| static inline void set_page_count(struct page *page, int v) |
| { |
| atomic_set(&page->_count, v); |
| } |
| |
| /* |
| * Turn a non-refcounted page (->_count == 0) into refcounted with |
| * a count of one. |
| */ |
| static inline void set_page_refcounted(struct page *page) |
| { |
| VM_BUG_ON(PageTail(page)); |
| VM_BUG_ON(atomic_read(&page->_count)); |
| set_page_count(page, 1); |
| } |
| |
| /* |
| * split_page takes a non-compound higher-order page, and splits it into |
| * n (1<<order) sub-pages: page[0..n] |
| * Each sub-page must be freed individually. |
| * |
| * Note: this is probably too low level an operation for use in drivers. |
| * Please consult with lkml before using this in your driver. |
| */ |
| void split_page(struct page *page, unsigned int order) |
| { |
| int i; |
| |
| VM_BUG_ON(PageCompound(page)); |
| VM_BUG_ON(!page_count(page)); |
| |
| #ifdef CONFIG_KMEMCHECK |
| /* |
| * Split shadow pages too, because free(page[0]) would |
| * otherwise free the whole shadow. |
| */ |
| if (kmemcheck_page_is_tracked(page)) |
| split_page(virt_to_page(page[0].shadow), order); |
| #endif |
| |
| for (i = 1; i < (1 << order); i++) |
| set_page_refcounted(page + i); |
| } |
| EXPORT_SYMBOL_GPL(split_page); |