* [PATCH 00/15] staging: gasket: cleanups continue
@ 2018-07-31 20:24 Todd Poynor
2018-07-31 20:24 ` [PATCH 01/15] staging: gasket: core: remove static function forward declarations Todd Poynor
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
More cleanups for the gasket and apex drivers: finish up TODO items
for static function forward declarations and multi-line alignment
style, a couple of fixups for recent patch feedback, and a couple
other issues found in the meantime.
Todd Poynor (15):
staging: gasket: core: remove static function forward declarations
staging: gasket: ioctl: remove static function forward declarations
staging: gasket: interrupt: remove static function forward
declarations
staging: gasket: pg tbl: remove static function forward declarations
staging: gasket: TODO: remove entry for static function declarations
staging: gasket: core: fix function param line continuation style
staging: gasket: ioctl: fix function param line continuation style
staging: gasket: page table: fix function param line continuation
style
staging: gasket: sysfs: fix function param line continuation style
staging: gasket: interrupt: fix function param line continuation style
staging: gasket: TODO: remove entry for multi-line alignment style
staging: gasket: apex: move driver-private defines out of apex.h
staging: gasket: core: use bool type for ns_capable result
Revert "staging: gasket: page table: hold references to device and
pci_dev"
staging: gasket: page table: fix header file include guard symbol
drivers/staging/gasket/TODO | 4 -
drivers/staging/gasket/apex.h | 62 +-
drivers/staging/gasket/apex_driver.c | 29 +
drivers/staging/gasket/gasket_core.c | 2040 ++++++++++----------
drivers/staging/gasket/gasket_core.h | 68 +-
drivers/staging/gasket/gasket_interrupt.c | 530 +++--
drivers/staging/gasket/gasket_interrupt.h | 19 +-
drivers/staging/gasket/gasket_ioctl.c | 412 ++--
drivers/staging/gasket/gasket_page_table.c | 1434 +++++++-------
drivers/staging/gasket/gasket_page_table.h | 39 +-
drivers/staging/gasket/gasket_sysfs.c | 26 +-
drivers/staging/gasket/gasket_sysfs.h | 32 +-
12 files changed, 2248 insertions(+), 2447 deletions(-)
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 01/15] staging: gasket: core: remove static function forward declarations
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 02/15] staging: gasket: ioctl: " Todd Poynor
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
Remove forward declarations of static functions, move code to avoid
forward references, for kernel style.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/gasket_core.c | 1900 +++++++++++++-------------
1 file changed, 922 insertions(+), 978 deletions(-)
diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c
index c00774059f9e..b5a7254fbfb3 100644
--- a/drivers/staging/gasket/gasket_core.c
+++ b/drivers/staging/gasket/gasket_core.c
@@ -67,61 +67,6 @@ enum do_map_region_status {
DO_MAP_REGION_INVALID,
};
-/* Function declarations; comments are with definitions. */
-static int __init gasket_init(void);
-static void __exit gasket_exit(void);
-
-static int gasket_pci_probe(
- struct pci_dev *pci_dev, const struct pci_device_id *id);
-static void gasket_pci_remove(struct pci_dev *pci_dev);
-
-static int gasket_setup_pci(struct pci_dev *pci_dev, struct gasket_dev *dev);
-static void gasket_cleanup_pci(struct gasket_dev *dev);
-
-static int gasket_map_pci_bar(struct gasket_dev *dev, int bar_num);
-static void gasket_unmap_pci_bar(struct gasket_dev *dev, int bar_num);
-
-static int gasket_alloc_dev(
- struct gasket_internal_desc *internal_desc, struct device *dev,
- struct gasket_dev **pdev, const char *kobj_name);
-static void gasket_free_dev(struct gasket_dev *dev);
-
-static int gasket_find_dev_slot(
- struct gasket_internal_desc *internal_desc, const char *kobj_name);
-
-static int gasket_add_cdev(
- struct gasket_cdev_info *dev_info,
- const struct file_operations *file_ops, struct module *owner);
-
-static int gasket_enable_dev(
- struct gasket_internal_desc *internal_desc,
- struct gasket_dev *gasket_dev);
-static void gasket_disable_dev(struct gasket_dev *gasket_dev);
-
-static struct gasket_internal_desc *lookup_internal_desc(
- struct pci_dev *pci_dev);
-
-static ssize_t gasket_sysfs_data_show(
- struct device *device, struct device_attribute *attr, char *buf);
-
-static int gasket_mmap(struct file *filp, struct vm_area_struct *vma);
-static int gasket_open(struct inode *inode, struct file *file);
-static int gasket_release(struct inode *inode, struct file *file);
-static long gasket_ioctl(struct file *filp, uint cmd, ulong arg);
-
-static int gasket_mm_vma_bar_offset(
- const struct gasket_dev *gasket_dev, const struct vm_area_struct *vma,
- ulong *bar_offset);
-static bool gasket_mm_get_mapping_addrs(
- const struct gasket_mappable_region *region, ulong bar_offset,
- ulong requested_length, struct gasket_mappable_region *mappable_region,
- ulong *virt_offset);
-static enum do_map_region_status do_map_region(
- const struct gasket_dev *gasket_dev, struct vm_area_struct *vma,
- struct gasket_mappable_region *map_region);
-
-static int gasket_get_hw_status(struct gasket_dev *gasket_dev);
-
/* Global data definitions. */
/* Mutex - only for framework-wide data. Other data should be protected by
* finer-grained locks.
@@ -157,48 +102,6 @@ enum gasket_sysfs_attribute_type {
ATTR_USER_MEM_RANGES
};
-/* File operations for all Gasket devices. */
-static const struct file_operations gasket_file_ops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .mmap = gasket_mmap,
- .open = gasket_open,
- .release = gasket_release,
- .unlocked_ioctl = gasket_ioctl,
-};
-
-/* These attributes apply to all Gasket driver instances. */
-static const struct gasket_sysfs_attribute gasket_sysfs_generic_attrs[] = {
- GASKET_SYSFS_RO(bar_offsets, gasket_sysfs_data_show, ATTR_BAR_OFFSETS),
- GASKET_SYSFS_RO(bar_sizes, gasket_sysfs_data_show, ATTR_BAR_SIZES),
- GASKET_SYSFS_RO(driver_version, gasket_sysfs_data_show,
- ATTR_DRIVER_VERSION),
- GASKET_SYSFS_RO(framework_version, gasket_sysfs_data_show,
- ATTR_FRAMEWORK_VERSION),
- GASKET_SYSFS_RO(device_type, gasket_sysfs_data_show, ATTR_DEVICE_TYPE),
- GASKET_SYSFS_RO(revision, gasket_sysfs_data_show,
- ATTR_HARDWARE_REVISION),
- GASKET_SYSFS_RO(pci_address, gasket_sysfs_data_show, ATTR_PCI_ADDRESS),
- GASKET_SYSFS_RO(status, gasket_sysfs_data_show, ATTR_STATUS),
- GASKET_SYSFS_RO(is_device_owned, gasket_sysfs_data_show,
- ATTR_IS_DEVICE_OWNED),
- GASKET_SYSFS_RO(device_owner, gasket_sysfs_data_show,
- ATTR_DEVICE_OWNER),
- GASKET_SYSFS_RO(write_open_count, gasket_sysfs_data_show,
- ATTR_WRITE_OPEN_COUNT),
- GASKET_SYSFS_RO(reset_count, gasket_sysfs_data_show, ATTR_RESET_COUNT),
- GASKET_SYSFS_RO(user_mem_ranges, gasket_sysfs_data_show,
- ATTR_USER_MEM_RANGES),
- GASKET_END_OF_ATTR_ARRAY
-};
-
-MODULE_DESCRIPTION("Google Gasket driver framework");
-MODULE_VERSION(GASKET_FRAMEWORK_VERSION);
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Rob Springer <rspringer@google.com>");
-module_init(gasket_init);
-module_exit(gasket_exit);
-
/* Perform a standard Gasket callback. */
static inline int check_and_invoke_callback(
struct gasket_dev *gasket_dev, int (*cb_function)(struct gasket_dev *))
@@ -239,165 +142,43 @@ static int gasket_owned_by_current_tgid(struct gasket_cdev_info *info)
(info->ownership.owner == current->tgid));
}
-static int __init gasket_init(void)
+/*
+ * Find the next free gasket_internal_dev slot.
+ *
+ * Returns the located slot number on success or a negative number on failure.
+ */
+static int gasket_find_dev_slot(
+ struct gasket_internal_desc *internal_desc, const char *kobj_name)
{
int i;
- pr_info("Performing one-time init of the Gasket framework.\n");
- /* Check for duplicates and find a free slot. */
- mutex_lock(&g_mutex);
- for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
- g_descs[i].driver_desc = NULL;
- mutex_init(&g_descs[i].mutex);
- }
-
- gasket_sysfs_init();
-
- mutex_unlock(&g_mutex);
- return 0;
-}
-
-static void __exit gasket_exit(void)
-{
- /* No deinit/dealloc needed at present. */
- pr_info("Removing Gasket framework module.\n");
-}
-
-/* See gasket_core.h for description. */
-int gasket_register_device(const struct gasket_driver_desc *driver_desc)
-{
- int i, ret;
- int desc_idx = -1;
- struct gasket_internal_desc *internal;
-
- pr_info("Initializing Gasket framework device\n");
- /* Check for duplicates and find a free slot. */
- mutex_lock(&g_mutex);
+ mutex_lock(&internal_desc->mutex);
- for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
- if (g_descs[i].driver_desc == driver_desc) {
- pr_err("%s driver already loaded/registered\n",
- driver_desc->name);
- mutex_unlock(&g_mutex);
+ /* Search for a previous instance of this device. */
+ for (i = 0; i < GASKET_DEV_MAX; i++) {
+ if (internal_desc->devs[i] &&
+ strcmp(internal_desc->devs[i]->kobj_name, kobj_name) == 0) {
+ pr_err("Duplicate device %s\n", kobj_name);
+ mutex_unlock(&internal_desc->mutex);
return -EBUSY;
}
}
- /* This and the above loop could be combined, but this reads easier. */
- for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
- if (!g_descs[i].driver_desc) {
- g_descs[i].driver_desc = driver_desc;
- desc_idx = i;
+ /* Find a free device slot. */
+ for (i = 0; i < GASKET_DEV_MAX; i++) {
+ if (!internal_desc->devs[i])
break;
- }
}
- mutex_unlock(&g_mutex);
-
- pr_info("Loaded %s driver, framework version %s\n",
- driver_desc->name, GASKET_FRAMEWORK_VERSION);
- if (desc_idx == -1) {
- pr_err("Too many Gasket drivers loaded: %d\n",
- GASKET_FRAMEWORK_DESC_MAX);
+ if (i == GASKET_DEV_MAX) {
+ pr_err("Too many registered devices; max %d\n", GASKET_DEV_MAX);
+ mutex_unlock(&internal_desc->mutex);
return -EBUSY;
}
- /* Internal structure setup. */
- pr_debug("Performing initial internal structure setup.\n");
- internal = &g_descs[desc_idx];
- mutex_init(&internal->mutex);
- memset(internal->devs, 0, sizeof(struct gasket_dev *) * GASKET_DEV_MAX);
- memset(&internal->pci, 0, sizeof(internal->pci));
- internal->pci.name = driver_desc->name;
- internal->pci.id_table = driver_desc->pci_id_table;
- internal->pci.probe = gasket_pci_probe;
- internal->pci.remove = gasket_pci_remove;
- internal->class =
- class_create(driver_desc->module, driver_desc->name);
-
- if (IS_ERR(internal->class)) {
- pr_err("Cannot register %s class [ret=%ld]\n",
- driver_desc->name, PTR_ERR(internal->class));
- ret = PTR_ERR(internal->class);
- goto unregister_gasket_driver;
- }
-
- /*
- * Not using pci_register_driver() (without underscores), as it
- * depends on KBUILD_MODNAME, and this is a shared file.
- */
- pr_debug("Registering PCI driver.\n");
- ret = __pci_register_driver(
- &internal->pci, driver_desc->module, driver_desc->name);
- if (ret) {
- pr_err("cannot register pci driver [ret=%d]\n", ret);
- goto fail1;
- }
-
- pr_debug("Registering char driver.\n");
- ret = register_chrdev_region(
- MKDEV(driver_desc->major, driver_desc->minor), GASKET_DEV_MAX,
- driver_desc->name);
- if (ret) {
- pr_err("cannot register char driver [ret=%d]\n", ret);
- goto fail2;
- }
-
- pr_info("Driver registered successfully.\n");
- return 0;
-
-fail2:
- pci_unregister_driver(&internal->pci);
-
-fail1:
- class_destroy(internal->class);
-
-unregister_gasket_driver:
- mutex_lock(&g_mutex);
- g_descs[desc_idx].driver_desc = NULL;
- mutex_unlock(&g_mutex);
- return ret;
-}
-EXPORT_SYMBOL(gasket_register_device);
-
-/* See gasket_core.h for description. */
-void gasket_unregister_device(const struct gasket_driver_desc *driver_desc)
-{
- int i, desc_idx;
- struct gasket_internal_desc *internal_desc = NULL;
-
- mutex_lock(&g_mutex);
- for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
- if (g_descs[i].driver_desc == driver_desc) {
- internal_desc = &g_descs[i];
- desc_idx = i;
- break;
- }
- }
- mutex_unlock(&g_mutex);
-
- if (!internal_desc) {
- pr_err("request to unregister unknown desc: %s, %d:%d\n",
- driver_desc->name, driver_desc->major,
- driver_desc->minor);
- return;
- }
-
- unregister_chrdev_region(
- MKDEV(driver_desc->major, driver_desc->minor), GASKET_DEV_MAX);
-
- pci_unregister_driver(&internal_desc->pci);
-
- class_destroy(internal_desc->class);
-
- /* Finally, effectively "remove" the driver. */
- mutex_lock(&g_mutex);
- g_descs[desc_idx].driver_desc = NULL;
- mutex_unlock(&g_mutex);
-
- pr_info("removed %s driver\n", driver_desc->name);
+ mutex_unlock(&internal_desc->mutex);
+ return i;
}
-EXPORT_SYMBOL(gasket_unregister_device);
/*
* Allocate and initialize a Gasket device structure, add the device to the
@@ -474,265 +255,21 @@ static void gasket_free_dev(struct gasket_dev *gasket_dev)
}
/*
- * Find the next free gasket_internal_dev slot.
+ * Maps the specified bar into kernel space.
*
- * Returns the located slot number on success or a negative number on failure.
+ * Returns 0 on success, a negative error code otherwise.
+ * A zero-sized BAR will not be mapped, but is not an error.
*/
-static int gasket_find_dev_slot(
- struct gasket_internal_desc *internal_desc, const char *kobj_name)
+static int gasket_map_pci_bar(struct gasket_dev *gasket_dev, int bar_num)
{
- int i;
+ struct gasket_internal_desc *internal_desc = gasket_dev->internal_desc;
+ const struct gasket_driver_desc *driver_desc =
+ internal_desc->driver_desc;
+ ulong desc_bytes = driver_desc->bar_descriptions[bar_num].size;
+ int ret;
- mutex_lock(&internal_desc->mutex);
-
- /* Search for a previous instance of this device. */
- for (i = 0; i < GASKET_DEV_MAX; i++) {
- if (internal_desc->devs[i] &&
- strcmp(internal_desc->devs[i]->kobj_name, kobj_name) == 0) {
- pr_err("Duplicate device %s\n", kobj_name);
- mutex_unlock(&internal_desc->mutex);
- return -EBUSY;
- }
- }
-
- /* Find a free device slot. */
- for (i = 0; i < GASKET_DEV_MAX; i++) {
- if (!internal_desc->devs[i])
- break;
- }
-
- if (i == GASKET_DEV_MAX) {
- pr_err("Too many registered devices; max %d\n", GASKET_DEV_MAX);
- mutex_unlock(&internal_desc->mutex);
- return -EBUSY;
- }
-
- mutex_unlock(&internal_desc->mutex);
- return i;
-}
-
-/*
- * PCI subsystem probe function.
- *
- * Called when a Gasket device is found. Allocates device metadata, maps device
- * memory, and calls gasket_enable_dev to prepare the device for active use.
- *
- * Returns 0 if successful and a negative value otherwise.
- */
-static int gasket_pci_probe(
- struct pci_dev *pci_dev, const struct pci_device_id *id)
-{
- int ret;
- const char *kobj_name = dev_name(&pci_dev->dev);
- struct gasket_internal_desc *internal_desc;
- struct gasket_dev *gasket_dev;
- const struct gasket_driver_desc *driver_desc;
- struct device *parent;
-
- pr_info("Add Gasket device %s\n", kobj_name);
-
- mutex_lock(&g_mutex);
- internal_desc = lookup_internal_desc(pci_dev);
- mutex_unlock(&g_mutex);
- if (!internal_desc) {
- pr_err("PCI probe called for unknown driver type\n");
- return -ENODEV;
- }
-
- driver_desc = internal_desc->driver_desc;
-
- parent = &pci_dev->dev;
- ret = gasket_alloc_dev(internal_desc, parent, &gasket_dev, kobj_name);
- if (ret)
- return ret;
- gasket_dev->pci_dev = pci_dev_get(pci_dev);
- if (IS_ERR_OR_NULL(gasket_dev->dev_info.device)) {
- pr_err("Cannot create %s device %s [ret = %ld]\n",
- driver_desc->name, gasket_dev->dev_info.name,
- PTR_ERR(gasket_dev->dev_info.device));
- ret = -ENODEV;
- goto fail1;
- }
-
- ret = gasket_setup_pci(pci_dev, gasket_dev);
- if (ret)
- goto fail2;
-
- ret = check_and_invoke_callback(gasket_dev, driver_desc->add_dev_cb);
- if (ret) {
- dev_err(gasket_dev->dev, "Error in add device cb: %d\n", ret);
- goto fail2;
- }
-
- ret = gasket_sysfs_create_mapping(
- gasket_dev->dev_info.device, gasket_dev);
- if (ret)
- goto fail3;
-
- /*
- * Once we've created the mapping structures successfully, attempt to
- * create a symlink to the pci directory of this object.
- */
- ret = sysfs_create_link(&gasket_dev->dev_info.device->kobj,
- &pci_dev->dev.kobj, dev_name(&pci_dev->dev));
- if (ret) {
- dev_err(gasket_dev->dev,
- "Cannot create sysfs pci link: %d\n", ret);
- goto fail3;
- }
- ret = gasket_sysfs_create_entries(
- gasket_dev->dev_info.device, gasket_sysfs_generic_attrs);
- if (ret)
- goto fail4;
-
- ret = check_and_invoke_callback(
- gasket_dev, driver_desc->sysfs_setup_cb);
- if (ret) {
- dev_err(gasket_dev->dev, "Error in sysfs setup cb: %d\n", ret);
- goto fail5;
- }
-
- ret = gasket_enable_dev(internal_desc, gasket_dev);
- if (ret) {
- pr_err("cannot setup %s device\n", driver_desc->name);
- gasket_disable_dev(gasket_dev);
- goto fail5;
- }
-
- return 0;
-
-fail5:
- check_and_invoke_callback(gasket_dev, driver_desc->sysfs_cleanup_cb);
-fail4:
-fail3:
- gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
-fail2:
- gasket_cleanup_pci(gasket_dev);
- check_and_invoke_callback(gasket_dev, driver_desc->remove_dev_cb);
- device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
-fail1:
- gasket_free_dev(gasket_dev);
- return ret;
-}
-
-/*
- * PCI subsystem remove function.
- *
- * Called to remove a Gasket device. Finds the device in the device list and
- * cleans up metadata.
- */
-static void gasket_pci_remove(struct pci_dev *pci_dev)
-{
- int i;
- struct gasket_internal_desc *internal_desc;
- struct gasket_dev *gasket_dev = NULL;
- const struct gasket_driver_desc *driver_desc;
- /* Find the device desc. */
- mutex_lock(&g_mutex);
- internal_desc = lookup_internal_desc(pci_dev);
- if (!internal_desc) {
- mutex_unlock(&g_mutex);
- return;
- }
- mutex_unlock(&g_mutex);
-
- driver_desc = internal_desc->driver_desc;
-
- /* Now find the specific device */
- mutex_lock(&internal_desc->mutex);
- for (i = 0; i < GASKET_DEV_MAX; i++) {
- if (internal_desc->devs[i] &&
- internal_desc->devs[i]->pci_dev == pci_dev) {
- gasket_dev = internal_desc->devs[i];
- break;
- }
- }
- mutex_unlock(&internal_desc->mutex);
-
- if (!gasket_dev)
- return;
-
- pr_info("remove %s device %s\n", internal_desc->driver_desc->name,
- gasket_dev->kobj_name);
-
- gasket_disable_dev(gasket_dev);
- gasket_cleanup_pci(gasket_dev);
-
- check_and_invoke_callback(gasket_dev, driver_desc->sysfs_cleanup_cb);
- gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
-
- check_and_invoke_callback(gasket_dev, driver_desc->remove_dev_cb);
-
- device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
- gasket_free_dev(gasket_dev);
-}
-
-/*
- * Setup PCI & set up memory mapping for the specified device.
- *
- * Enables the PCI device, reads the BAR registers and sets up pointers to the
- * device's memory mapped IO space.
- *
- * Returns 0 on success and a negative value otherwise.
- */
-static int gasket_setup_pci(
- struct pci_dev *pci_dev, struct gasket_dev *gasket_dev)
-{
- int i, mapped_bars, ret;
-
- ret = pci_enable_device(pci_dev);
- if (ret) {
- dev_err(gasket_dev->dev, "cannot enable PCI device\n");
- return ret;
- }
-
- pci_set_master(pci_dev);
-
- for (i = 0; i < GASKET_NUM_BARS; i++) {
- ret = gasket_map_pci_bar(gasket_dev, i);
- if (ret) {
- mapped_bars = i;
- goto fail;
- }
- }
-
- return 0;
-
-fail:
- for (i = 0; i < mapped_bars; i++)
- gasket_unmap_pci_bar(gasket_dev, i);
-
- pci_disable_device(pci_dev);
- return -ENOMEM;
-}
-
-/* Unmaps memory and cleans up PCI for the specified device. */
-static void gasket_cleanup_pci(struct gasket_dev *gasket_dev)
-{
- int i;
-
- for (i = 0; i < GASKET_NUM_BARS; i++)
- gasket_unmap_pci_bar(gasket_dev, i);
-
- pci_disable_device(gasket_dev->pci_dev);
-}
-
-/*
- * Maps the specified bar into kernel space.
- *
- * Returns 0 on success, a negative error code otherwise.
- * A zero-sized BAR will not be mapped, but is not an error.
- */
-static int gasket_map_pci_bar(struct gasket_dev *gasket_dev, int bar_num)
-{
- struct gasket_internal_desc *internal_desc = gasket_dev->internal_desc;
- const struct gasket_driver_desc *driver_desc =
- internal_desc->driver_desc;
- ulong desc_bytes = driver_desc->bar_descriptions[bar_num].size;
- int ret;
-
- if (desc_bytes == 0)
- return 0;
+ if (desc_bytes == 0)
+ return 0;
if (driver_desc->bar_descriptions[bar_num].type != PCI_BAR) {
/* not PCI: skip this entry */
@@ -826,320 +363,329 @@ static void gasket_unmap_pci_bar(struct gasket_dev *dev, int bar_num)
release_mem_region(base, bytes);
}
-/* Add a char device and related info. */
-static int gasket_add_cdev(
- struct gasket_cdev_info *dev_info,
- const struct file_operations *file_ops, struct module *owner)
-{
- int ret;
-
- cdev_init(&dev_info->cdev, file_ops);
- dev_info->cdev.owner = owner;
- ret = cdev_add(&dev_info->cdev, dev_info->devt, 1);
- if (ret) {
- dev_err(dev_info->gasket_dev_ptr->dev,
- "cannot add char device [ret=%d]\n", ret);
- return ret;
- }
- dev_info->cdev_added = 1;
-
- return 0;
-}
-
-/* Perform final init and marks the device as active. */
-static int gasket_enable_dev(
- struct gasket_internal_desc *internal_desc,
- struct gasket_dev *gasket_dev)
+/*
+ * Setup PCI & set up memory mapping for the specified device.
+ *
+ * Enables the PCI device, reads the BAR registers and sets up pointers to the
+ * device's memory mapped IO space.
+ *
+ * Returns 0 on success and a negative value otherwise.
+ */
+static int gasket_setup_pci(
+ struct pci_dev *pci_dev, struct gasket_dev *gasket_dev)
{
- int tbl_idx;
- int ret;
- const struct gasket_driver_desc *driver_desc =
- internal_desc->driver_desc;
+ int i, mapped_bars, ret;
- ret = gasket_interrupt_init(
- gasket_dev, driver_desc->name,
- driver_desc->interrupt_type, driver_desc->interrupts,
- driver_desc->num_interrupts, driver_desc->interrupt_pack_width,
- driver_desc->interrupt_bar_index,
- driver_desc->wire_interrupt_offsets);
+ ret = pci_enable_device(pci_dev);
if (ret) {
- dev_err(gasket_dev->dev,
- "Critical failure to allocate interrupts: %d\n", ret);
- gasket_interrupt_cleanup(gasket_dev);
+ dev_err(gasket_dev->dev, "cannot enable PCI device\n");
return ret;
}
- for (tbl_idx = 0; tbl_idx < driver_desc->num_page_tables; tbl_idx++) {
- dev_dbg(gasket_dev->dev, "Initializing page table %d.\n",
- tbl_idx);
- ret = gasket_page_table_init(
- &gasket_dev->page_table[tbl_idx],
- &gasket_dev->bar_data[
- driver_desc->page_table_bar_index],
- &driver_desc->page_table_configs[tbl_idx],
- gasket_dev->dev, gasket_dev->pci_dev);
+ pci_set_master(pci_dev);
+
+ for (i = 0; i < GASKET_NUM_BARS; i++) {
+ ret = gasket_map_pci_bar(gasket_dev, i);
if (ret) {
- dev_err(gasket_dev->dev,
- "Couldn't init page table %d: %d\n",
- tbl_idx, ret);
- return ret;
+ mapped_bars = i;
+ goto fail;
}
- /*
- * Make sure that the page table is clear and set to simple
- * addresses.
- */
- gasket_page_table_reset(gasket_dev->page_table[tbl_idx]);
}
- /*
- * hardware_revision_cb returns a positive integer (the rev) if
- * successful.)
- */
- ret = check_and_invoke_callback(
- gasket_dev, driver_desc->hardware_revision_cb);
- if (ret < 0) {
- dev_err(gasket_dev->dev,
- "Error getting hardware revision: %d\n", ret);
- return ret;
- }
- gasket_dev->hardware_revision = ret;
+ return 0;
- ret = check_and_invoke_callback(gasket_dev, driver_desc->enable_dev_cb);
- if (ret) {
- dev_err(gasket_dev->dev, "Error in enable device cb: %d\n",
- ret);
- return ret;
- }
+fail:
+ for (i = 0; i < mapped_bars; i++)
+ gasket_unmap_pci_bar(gasket_dev, i);
- /* device_status_cb returns a device status, not an error code. */
- gasket_dev->status = gasket_get_hw_status(gasket_dev);
- if (gasket_dev->status == GASKET_STATUS_DEAD)
- dev_err(gasket_dev->dev, "Device reported as unhealthy.\n");
+ pci_disable_device(pci_dev);
+ return -ENOMEM;
+}
- ret = gasket_add_cdev(
- &gasket_dev->dev_info, &gasket_file_ops, driver_desc->module);
- if (ret)
- return ret;
+/* Unmaps memory and cleans up PCI for the specified device. */
+static void gasket_cleanup_pci(struct gasket_dev *gasket_dev)
+{
+ int i;
- return 0;
+ for (i = 0; i < GASKET_NUM_BARS; i++)
+ gasket_unmap_pci_bar(gasket_dev, i);
+
+ pci_disable_device(gasket_dev->pci_dev);
}
-/* Disable device operations. */
-static void gasket_disable_dev(struct gasket_dev *gasket_dev)
+/* Determine the health of the Gasket device. */
+static int gasket_get_hw_status(struct gasket_dev *gasket_dev)
{
+ int status;
+ int i;
const struct gasket_driver_desc *driver_desc =
gasket_dev->internal_desc->driver_desc;
- int i;
-
- /* Only delete the device if it has been successfully added. */
- if (gasket_dev->dev_info.cdev_added)
- cdev_del(&gasket_dev->dev_info.cdev);
- gasket_dev->status = GASKET_STATUS_DEAD;
+ status = gasket_check_and_invoke_callback_nolock(
+ gasket_dev, driver_desc->device_status_cb);
+ if (status != GASKET_STATUS_ALIVE) {
+ dev_dbg(gasket_dev->dev, "Hardware reported status %d.\n",
+ status);
+ return status;
+ }
- gasket_interrupt_cleanup(gasket_dev);
+ status = gasket_interrupt_system_status(gasket_dev);
+ if (status != GASKET_STATUS_ALIVE) {
+ dev_dbg(gasket_dev->dev,
+ "Interrupt system reported status %d.\n", status);
+ return status;
+ }
for (i = 0; i < driver_desc->num_page_tables; ++i) {
- if (gasket_dev->page_table[i]) {
- gasket_page_table_reset(gasket_dev->page_table[i]);
- gasket_page_table_cleanup(gasket_dev->page_table[i]);
+ status = gasket_page_table_system_status(
+ gasket_dev->page_table[i]);
+ if (status != GASKET_STATUS_ALIVE) {
+ dev_dbg(gasket_dev->dev,
+ "Page table %d reported status %d.\n",
+ i, status);
+ return status;
}
}
- check_and_invoke_callback(gasket_dev, driver_desc->disable_dev_cb);
+ return GASKET_STATUS_ALIVE;
}
-/*
- * Registered descriptor lookup.
- *
- * Precondition: Called with g_mutex held (to avoid a race on return).
- * Returns NULL if no matching device was found.
- */
-static struct gasket_internal_desc *lookup_internal_desc(
- struct pci_dev *pci_dev)
+static ssize_t gasket_write_mappable_regions(
+ char *buf, const struct gasket_driver_desc *driver_desc, int bar_index)
{
int i;
+ ssize_t written;
+ ssize_t total_written = 0;
+ ulong min_addr, max_addr;
+ struct gasket_bar_desc bar_desc =
+ driver_desc->bar_descriptions[bar_index];
- __must_hold(&g_mutex);
- for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
- if (g_descs[i].driver_desc &&
- g_descs[i].driver_desc->pci_id_table &&
- pci_match_id(g_descs[i].driver_desc->pci_id_table, pci_dev))
- return &g_descs[i];
+ if (bar_desc.permissions == GASKET_NOMAP)
+ return 0;
+ for (i = 0;
+ i < bar_desc.num_mappable_regions && total_written < PAGE_SIZE;
+ i++) {
+ min_addr = bar_desc.mappable_regions[i].start -
+ driver_desc->legacy_mmap_address_offset;
+ max_addr = bar_desc.mappable_regions[i].start -
+ driver_desc->legacy_mmap_address_offset +
+ bar_desc.mappable_regions[i].length_bytes;
+ written = scnprintf(buf, PAGE_SIZE - total_written,
+ "0x%08lx-0x%08lx\n", min_addr, max_addr);
+ total_written += written;
+ buf += written;
}
-
- return NULL;
+ return total_written;
}
-/**
- * Lookup a name by number in a num_name table.
- * @num: Number to lookup.
- * @table: Array of num_name structures, the table for the lookup.
- *
- * Description: Searches for num in the table. If found, the
- * corresponding name is returned; otherwise NULL
- * is returned.
- *
- * The table must have a NULL name pointer at the end.
- */
-const char *gasket_num_name_lookup(
- uint num, const struct gasket_num_name *table)
+static ssize_t gasket_sysfs_data_show(
+ struct device *device, struct device_attribute *attr, char *buf)
{
- uint i = 0;
+ int i, ret = 0;
+ ssize_t current_written = 0;
+ const struct gasket_driver_desc *driver_desc;
+ struct gasket_dev *gasket_dev;
+ struct gasket_sysfs_attribute *gasket_attr;
+ const struct gasket_bar_desc *bar_desc;
+ enum gasket_sysfs_attribute_type sysfs_type;
- while (table[i].snn_name) {
- if (num == table[i].snn_num)
- break;
- ++i;
+ gasket_dev = gasket_sysfs_get_device_data(device);
+ if (!gasket_dev) {
+ dev_err(device, "No sysfs mapping found for device\n");
+ return 0;
}
- return table[i].snn_name;
-}
-EXPORT_SYMBOL(gasket_num_name_lookup);
-
-/*
- * Open the char device file.
- *
- * If the open is for writing, and the device is not owned, this process becomes
- * the owner. If the open is for writing and the device is already owned by
- * some other process, it is an error. If this process is the owner, increment
- * the open count.
- *
- * Returns 0 if successful, a negative error number otherwise.
- */
-static int gasket_open(struct inode *inode, struct file *filp)
-{
- int ret;
- struct gasket_dev *gasket_dev;
- const struct gasket_driver_desc *driver_desc;
- struct gasket_ownership *ownership;
- char task_name[TASK_COMM_LEN];
- struct gasket_cdev_info *dev_info =
- container_of(inode->i_cdev, struct gasket_cdev_info, cdev);
- struct pid_namespace *pid_ns = task_active_pid_ns(current);
- int is_root = ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN);
+ gasket_attr = gasket_sysfs_get_attr(device, attr);
+ if (!gasket_attr) {
+ dev_err(device, "No sysfs attr found for device\n");
+ gasket_sysfs_put_device_data(device, gasket_dev);
+ return 0;
+ }
- gasket_dev = dev_info->gasket_dev_ptr;
driver_desc = gasket_dev->internal_desc->driver_desc;
- ownership = &dev_info->ownership;
- get_task_comm(task_name, current);
- filp->private_data = gasket_dev;
- inode->i_size = 0;
-
- dev_dbg(gasket_dev->dev,
- "Attempting to open with tgid %u (%s) (f_mode: 0%03o, "
- "fmode_write: %d is_root: %u)\n",
- current->tgid, task_name, filp->f_mode,
- (filp->f_mode & FMODE_WRITE), is_root);
- /* Always allow non-writing accesses. */
- if (!(filp->f_mode & FMODE_WRITE)) {
- dev_dbg(gasket_dev->dev, "Allowing read-only opening.\n");
- return 0;
+ sysfs_type =
+ (enum gasket_sysfs_attribute_type)gasket_attr->data.attr_type;
+ switch (sysfs_type) {
+ case ATTR_BAR_OFFSETS:
+ for (i = 0; i < GASKET_NUM_BARS; i++) {
+ bar_desc = &driver_desc->bar_descriptions[i];
+ if (bar_desc->size == 0)
+ continue;
+ current_written =
+ snprintf(buf, PAGE_SIZE - ret, "%d: 0x%lx\n", i,
+ (ulong)bar_desc->base);
+ buf += current_written;
+ ret += current_written;
+ }
+ break;
+ case ATTR_BAR_SIZES:
+ for (i = 0; i < GASKET_NUM_BARS; i++) {
+ bar_desc = &driver_desc->bar_descriptions[i];
+ if (bar_desc->size == 0)
+ continue;
+ current_written =
+ snprintf(buf, PAGE_SIZE - ret, "%d: 0x%lx\n", i,
+ (ulong)bar_desc->size);
+ buf += current_written;
+ ret += current_written;
+ }
+ break;
+ case ATTR_DRIVER_VERSION:
+ ret = snprintf(
+ buf, PAGE_SIZE, "%s\n",
+ gasket_dev->internal_desc->driver_desc->driver_version);
+ break;
+ case ATTR_FRAMEWORK_VERSION:
+ ret = snprintf(
+ buf, PAGE_SIZE, "%s\n", GASKET_FRAMEWORK_VERSION);
+ break;
+ case ATTR_DEVICE_TYPE:
+ ret = snprintf(
+ buf, PAGE_SIZE, "%s\n",
+ gasket_dev->internal_desc->driver_desc->name);
+ break;
+ case ATTR_HARDWARE_REVISION:
+ ret = snprintf(
+ buf, PAGE_SIZE, "%d\n", gasket_dev->hardware_revision);
+ break;
+ case ATTR_PCI_ADDRESS:
+ ret = snprintf(buf, PAGE_SIZE, "%s\n", gasket_dev->kobj_name);
+ break;
+ case ATTR_STATUS:
+ ret = snprintf(
+ buf, PAGE_SIZE, "%s\n",
+ gasket_num_name_lookup(
+ gasket_dev->status, gasket_status_name_table));
+ break;
+ case ATTR_IS_DEVICE_OWNED:
+ ret = snprintf(
+ buf, PAGE_SIZE, "%d\n",
+ gasket_dev->dev_info.ownership.is_owned);
+ break;
+ case ATTR_DEVICE_OWNER:
+ ret = snprintf(
+ buf, PAGE_SIZE, "%d\n",
+ gasket_dev->dev_info.ownership.owner);
+ break;
+ case ATTR_WRITE_OPEN_COUNT:
+ ret = snprintf(
+ buf, PAGE_SIZE, "%d\n",
+ gasket_dev->dev_info.ownership.write_open_count);
+ break;
+ case ATTR_RESET_COUNT:
+ ret = snprintf(buf, PAGE_SIZE, "%d\n", gasket_dev->reset_count);
+ break;
+ case ATTR_USER_MEM_RANGES:
+ for (i = 0; i < GASKET_NUM_BARS; ++i) {
+ current_written = gasket_write_mappable_regions(
+ buf, driver_desc, i);
+ buf += current_written;
+ ret += current_written;
+ }
+ break;
+ default:
+ dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n",
+ attr->attr.name);
+ ret = 0;
+ break;
}
- mutex_lock(&gasket_dev->mutex);
+ gasket_sysfs_put_attr(device, gasket_attr);
+ gasket_sysfs_put_device_data(device, gasket_dev);
+ return ret;
+}
- dev_dbg(gasket_dev->dev,
- "Current owner open count (owning tgid %u): %d.\n",
- ownership->owner, ownership->write_open_count);
+/* These attributes apply to all Gasket driver instances. */
+static const struct gasket_sysfs_attribute gasket_sysfs_generic_attrs[] = {
+ GASKET_SYSFS_RO(bar_offsets, gasket_sysfs_data_show, ATTR_BAR_OFFSETS),
+ GASKET_SYSFS_RO(bar_sizes, gasket_sysfs_data_show, ATTR_BAR_SIZES),
+ GASKET_SYSFS_RO(driver_version, gasket_sysfs_data_show,
+ ATTR_DRIVER_VERSION),
+ GASKET_SYSFS_RO(framework_version, gasket_sysfs_data_show,
+ ATTR_FRAMEWORK_VERSION),
+ GASKET_SYSFS_RO(device_type, gasket_sysfs_data_show, ATTR_DEVICE_TYPE),
+ GASKET_SYSFS_RO(revision, gasket_sysfs_data_show,
+ ATTR_HARDWARE_REVISION),
+ GASKET_SYSFS_RO(pci_address, gasket_sysfs_data_show, ATTR_PCI_ADDRESS),
+ GASKET_SYSFS_RO(status, gasket_sysfs_data_show, ATTR_STATUS),
+ GASKET_SYSFS_RO(is_device_owned, gasket_sysfs_data_show,
+ ATTR_IS_DEVICE_OWNED),
+ GASKET_SYSFS_RO(device_owner, gasket_sysfs_data_show,
+ ATTR_DEVICE_OWNER),
+ GASKET_SYSFS_RO(write_open_count, gasket_sysfs_data_show,
+ ATTR_WRITE_OPEN_COUNT),
+ GASKET_SYSFS_RO(reset_count, gasket_sysfs_data_show, ATTR_RESET_COUNT),
+ GASKET_SYSFS_RO(user_mem_ranges, gasket_sysfs_data_show,
+ ATTR_USER_MEM_RANGES),
+ GASKET_END_OF_ATTR_ARRAY
+};
- /* Opening a node owned by another TGID is an error (unless root) */
- if (ownership->is_owned && ownership->owner != current->tgid &&
- !is_root) {
- dev_err(gasket_dev->dev,
- "Process %u is opening a node held by %u.\n",
- current->tgid, ownership->owner);
- mutex_unlock(&gasket_dev->mutex);
- return -EPERM;
- }
+/* Add a char device and related info. */
+static int gasket_add_cdev(
+ struct gasket_cdev_info *dev_info,
+ const struct file_operations *file_ops, struct module *owner)
+{
+ int ret;
- /* If the node is not owned, assign it to the current TGID. */
- if (!ownership->is_owned) {
- ret = gasket_check_and_invoke_callback_nolock(
- gasket_dev, driver_desc->device_open_cb);
- if (ret) {
- dev_err(gasket_dev->dev,
- "Error in device open cb: %d\n", ret);
- mutex_unlock(&gasket_dev->mutex);
- return ret;
- }
- ownership->is_owned = 1;
- ownership->owner = current->tgid;
- dev_dbg(gasket_dev->dev, "Device owner is now tgid %u\n",
- ownership->owner);
+ cdev_init(&dev_info->cdev, file_ops);
+ dev_info->cdev.owner = owner;
+ ret = cdev_add(&dev_info->cdev, dev_info->devt, 1);
+ if (ret) {
+ dev_err(dev_info->gasket_dev_ptr->dev,
+ "cannot add char device [ret=%d]\n", ret);
+ return ret;
}
+ dev_info->cdev_added = 1;
- ownership->write_open_count++;
-
- dev_dbg(gasket_dev->dev, "New open count (owning tgid %u): %d\n",
- ownership->owner, ownership->write_open_count);
-
- mutex_unlock(&gasket_dev->mutex);
return 0;
}
-/*
- * Called on a close of the device file. If this process is the owner,
- * decrement the open count. On last close by the owner, free up buffers and
- * eventfd contexts, and release ownership.
- *
- * Returns 0 if successful, a negative error number otherwise.
- */
-static int gasket_release(struct inode *inode, struct file *file)
+/* Disable device operations. */
+static void gasket_disable_dev(struct gasket_dev *gasket_dev)
{
+ const struct gasket_driver_desc *driver_desc =
+ gasket_dev->internal_desc->driver_desc;
int i;
- struct gasket_dev *gasket_dev;
- struct gasket_ownership *ownership;
- const struct gasket_driver_desc *driver_desc;
- char task_name[TASK_COMM_LEN];
- struct gasket_cdev_info *dev_info =
- container_of(inode->i_cdev, struct gasket_cdev_info, cdev);
- struct pid_namespace *pid_ns = task_active_pid_ns(current);
- int is_root = ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN);
- gasket_dev = dev_info->gasket_dev_ptr;
- driver_desc = gasket_dev->internal_desc->driver_desc;
- ownership = &dev_info->ownership;
- get_task_comm(task_name, current);
- mutex_lock(&gasket_dev->mutex);
+ /* Only delete the device if it has been successfully added. */
+ if (gasket_dev->dev_info.cdev_added)
+ cdev_del(&gasket_dev->dev_info.cdev);
- dev_dbg(gasket_dev->dev,
- "Releasing device node. Call origin: tgid %u (%s) "
- "(f_mode: 0%03o, fmode_write: %d, is_root: %u)\n",
- current->tgid, task_name, file->f_mode,
- (file->f_mode & FMODE_WRITE), is_root);
- dev_dbg(gasket_dev->dev, "Current open count (owning tgid %u): %d\n",
- ownership->owner, ownership->write_open_count);
+ gasket_dev->status = GASKET_STATUS_DEAD;
- if (file->f_mode & FMODE_WRITE) {
- ownership->write_open_count--;
- if (ownership->write_open_count == 0) {
- dev_dbg(gasket_dev->dev, "Device is now free\n");
- ownership->is_owned = 0;
- ownership->owner = 0;
+ gasket_interrupt_cleanup(gasket_dev);
- /* Forces chip reset before we unmap the page tables. */
- driver_desc->device_reset_cb(gasket_dev, 0);
+ for (i = 0; i < driver_desc->num_page_tables; ++i) {
+ if (gasket_dev->page_table[i]) {
+ gasket_page_table_reset(gasket_dev->page_table[i]);
+ gasket_page_table_cleanup(gasket_dev->page_table[i]);
+ }
+ }
- for (i = 0; i < driver_desc->num_page_tables; ++i) {
- gasket_page_table_unmap_all(
- gasket_dev->page_table[i]);
- gasket_page_table_garbage_collect(
- gasket_dev->page_table[i]);
- gasket_free_coherent_memory_all(gasket_dev, i);
- }
+ check_and_invoke_callback(gasket_dev, driver_desc->disable_dev_cb);
+}
- /* Closes device, enters power save. */
- gasket_check_and_invoke_callback_nolock(
- gasket_dev, driver_desc->device_close_cb);
- }
+/*
+ * Registered descriptor lookup.
+ *
+ * Precondition: Called with g_mutex held (to avoid a race on return).
+ * Returns NULL if no matching device was found.
+ */
+static struct gasket_internal_desc *lookup_internal_desc(
+ struct pci_dev *pci_dev)
+{
+ int i;
+
+ __must_hold(&g_mutex);
+ for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
+ if (g_descs[i].driver_desc &&
+ g_descs[i].driver_desc->pci_id_table &&
+ pci_match_id(g_descs[i].driver_desc->pci_id_table, pci_dev))
+ return &g_descs[i];
}
- dev_dbg(gasket_dev->dev, "New open count (owning tgid %u): %d\n",
- ownership->owner, ownership->write_open_count);
- mutex_unlock(&gasket_dev->mutex);
- return 0;
+ return NULL;
}
/*
@@ -1301,12 +847,42 @@ static bool gasket_mm_get_mapping_addrs(
return false;
}
-int gasket_mm_unmap_region(
- const struct gasket_dev *gasket_dev, struct vm_area_struct *vma,
- const struct gasket_mappable_region *map_region)
-{
- ulong bar_offset;
- ulong virt_offset;
+/*
+ * Calculates the offset where the VMA range begins in its containing BAR.
+ * The offset is written into bar_offset on success.
+ * Returns zero on success, anything else on error.
+ */
+static int gasket_mm_vma_bar_offset(
+ const struct gasket_dev *gasket_dev, const struct vm_area_struct *vma,
+ ulong *bar_offset)
+{
+ ulong raw_offset;
+ int bar_index;
+ const struct gasket_driver_desc *driver_desc =
+ gasket_dev->internal_desc->driver_desc;
+
+ raw_offset = (vma->vm_pgoff << PAGE_SHIFT) +
+ driver_desc->legacy_mmap_address_offset;
+ bar_index = gasket_get_bar_index(gasket_dev, raw_offset);
+ if (bar_index < 0) {
+ dev_err(gasket_dev->dev,
+ "Unable to find matching bar for address 0x%lx\n",
+ raw_offset);
+ trace_gasket_mmap_exit(bar_index);
+ return bar_index;
+ }
+ *bar_offset =
+ raw_offset - driver_desc->bar_descriptions[bar_index].base;
+
+ return 0;
+}
+
+int gasket_mm_unmap_region(
+ const struct gasket_dev *gasket_dev, struct vm_area_struct *vma,
+ const struct gasket_mappable_region *map_region)
+{
+ ulong bar_offset;
+ ulong virt_offset;
struct gasket_mappable_region mappable_region;
int ret;
@@ -1407,36 +983,6 @@ static enum do_map_region_status do_map_region(
return DO_MAP_REGION_FAILURE;
}
-/*
- * Calculates the offset where the VMA range begins in its containing BAR.
- * The offset is written into bar_offset on success.
- * Returns zero on success, anything else on error.
- */
-static int gasket_mm_vma_bar_offset(
- const struct gasket_dev *gasket_dev, const struct vm_area_struct *vma,
- ulong *bar_offset)
-{
- ulong raw_offset;
- int bar_index;
- const struct gasket_driver_desc *driver_desc =
- gasket_dev->internal_desc->driver_desc;
-
- raw_offset = (vma->vm_pgoff << PAGE_SHIFT) +
- driver_desc->legacy_mmap_address_offset;
- bar_index = gasket_get_bar_index(gasket_dev, raw_offset);
- if (bar_index < 0) {
- dev_err(gasket_dev->dev,
- "Unable to find matching bar for address 0x%lx\n",
- raw_offset);
- trace_gasket_mmap_exit(bar_index);
- return bar_index;
- }
- *bar_offset =
- raw_offset - driver_desc->bar_descriptions[bar_index].base;
-
- return 0;
-}
-
/* Map a region of coherent memory. */
static int gasket_mmap_coherent(
struct gasket_dev *gasket_dev, struct vm_area_struct *vma)
@@ -1626,41 +1172,149 @@ static int gasket_mmap(struct file *filp, struct vm_area_struct *vma)
return ret;
}
-/* Determine the health of the Gasket device. */
-static int gasket_get_hw_status(struct gasket_dev *gasket_dev)
+/*
+ * Open the char device file.
+ *
+ * If the open is for writing, and the device is not owned, this process becomes
+ * the owner. If the open is for writing and the device is already owned by
+ * some other process, it is an error. If this process is the owner, increment
+ * the open count.
+ *
+ * Returns 0 if successful, a negative error number otherwise.
+ */
+static int gasket_open(struct inode *inode, struct file *filp)
{
- int status;
- int i;
- const struct gasket_driver_desc *driver_desc =
- gasket_dev->internal_desc->driver_desc;
+ int ret;
+ struct gasket_dev *gasket_dev;
+ const struct gasket_driver_desc *driver_desc;
+ struct gasket_ownership *ownership;
+ char task_name[TASK_COMM_LEN];
+ struct gasket_cdev_info *dev_info =
+ container_of(inode->i_cdev, struct gasket_cdev_info, cdev);
+ struct pid_namespace *pid_ns = task_active_pid_ns(current);
+ int is_root = ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN);
- status = gasket_check_and_invoke_callback_nolock(
- gasket_dev, driver_desc->device_status_cb);
- if (status != GASKET_STATUS_ALIVE) {
- dev_dbg(gasket_dev->dev, "Hardware reported status %d.\n",
- status);
- return status;
+ gasket_dev = dev_info->gasket_dev_ptr;
+ driver_desc = gasket_dev->internal_desc->driver_desc;
+ ownership = &dev_info->ownership;
+ get_task_comm(task_name, current);
+ filp->private_data = gasket_dev;
+ inode->i_size = 0;
+
+ dev_dbg(gasket_dev->dev,
+ "Attempting to open with tgid %u (%s) (f_mode: 0%03o, "
+ "fmode_write: %d is_root: %u)\n",
+ current->tgid, task_name, filp->f_mode,
+ (filp->f_mode & FMODE_WRITE), is_root);
+
+ /* Always allow non-writing accesses. */
+ if (!(filp->f_mode & FMODE_WRITE)) {
+ dev_dbg(gasket_dev->dev, "Allowing read-only opening.\n");
+ return 0;
}
- status = gasket_interrupt_system_status(gasket_dev);
- if (status != GASKET_STATUS_ALIVE) {
- dev_dbg(gasket_dev->dev,
- "Interrupt system reported status %d.\n", status);
- return status;
+ mutex_lock(&gasket_dev->mutex);
+
+ dev_dbg(gasket_dev->dev,
+ "Current owner open count (owning tgid %u): %d.\n",
+ ownership->owner, ownership->write_open_count);
+
+ /* Opening a node owned by another TGID is an error (unless root) */
+ if (ownership->is_owned && ownership->owner != current->tgid &&
+ !is_root) {
+ dev_err(gasket_dev->dev,
+ "Process %u is opening a node held by %u.\n",
+ current->tgid, ownership->owner);
+ mutex_unlock(&gasket_dev->mutex);
+ return -EPERM;
}
- for (i = 0; i < driver_desc->num_page_tables; ++i) {
- status = gasket_page_table_system_status(
- gasket_dev->page_table[i]);
- if (status != GASKET_STATUS_ALIVE) {
- dev_dbg(gasket_dev->dev,
- "Page table %d reported status %d.\n",
- i, status);
- return status;
+ /* If the node is not owned, assign it to the current TGID. */
+ if (!ownership->is_owned) {
+ ret = gasket_check_and_invoke_callback_nolock(
+ gasket_dev, driver_desc->device_open_cb);
+ if (ret) {
+ dev_err(gasket_dev->dev,
+ "Error in device open cb: %d\n", ret);
+ mutex_unlock(&gasket_dev->mutex);
+ return ret;
}
+ ownership->is_owned = 1;
+ ownership->owner = current->tgid;
+ dev_dbg(gasket_dev->dev, "Device owner is now tgid %u\n",
+ ownership->owner);
}
- return GASKET_STATUS_ALIVE;
+ ownership->write_open_count++;
+
+ dev_dbg(gasket_dev->dev, "New open count (owning tgid %u): %d\n",
+ ownership->owner, ownership->write_open_count);
+
+ mutex_unlock(&gasket_dev->mutex);
+ return 0;
+}
+
+/*
+ * Called on a close of the device file. If this process is the owner,
+ * decrement the open count. On last close by the owner, free up buffers and
+ * eventfd contexts, and release ownership.
+ *
+ * Returns 0 if successful, a negative error number otherwise.
+ */
+static int gasket_release(struct inode *inode, struct file *file)
+{
+ int i;
+ struct gasket_dev *gasket_dev;
+ struct gasket_ownership *ownership;
+ const struct gasket_driver_desc *driver_desc;
+ char task_name[TASK_COMM_LEN];
+ struct gasket_cdev_info *dev_info =
+ container_of(inode->i_cdev, struct gasket_cdev_info, cdev);
+ struct pid_namespace *pid_ns = task_active_pid_ns(current);
+ int is_root = ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN);
+
+ gasket_dev = dev_info->gasket_dev_ptr;
+ driver_desc = gasket_dev->internal_desc->driver_desc;
+ ownership = &dev_info->ownership;
+ get_task_comm(task_name, current);
+ mutex_lock(&gasket_dev->mutex);
+
+ dev_dbg(gasket_dev->dev,
+ "Releasing device node. Call origin: tgid %u (%s) "
+ "(f_mode: 0%03o, fmode_write: %d, is_root: %u)\n",
+ current->tgid, task_name, file->f_mode,
+ (file->f_mode & FMODE_WRITE), is_root);
+ dev_dbg(gasket_dev->dev, "Current open count (owning tgid %u): %d\n",
+ ownership->owner, ownership->write_open_count);
+
+ if (file->f_mode & FMODE_WRITE) {
+ ownership->write_open_count--;
+ if (ownership->write_open_count == 0) {
+ dev_dbg(gasket_dev->dev, "Device is now free\n");
+ ownership->is_owned = 0;
+ ownership->owner = 0;
+
+ /* Forces chip reset before we unmap the page tables. */
+ driver_desc->device_reset_cb(gasket_dev, 0);
+
+ for (i = 0; i < driver_desc->num_page_tables; ++i) {
+ gasket_page_table_unmap_all(
+ gasket_dev->page_table[i]);
+ gasket_page_table_garbage_collect(
+ gasket_dev->page_table[i]);
+ gasket_free_coherent_memory_all(gasket_dev, i);
+ }
+
+ /* Closes device, enters power save. */
+ gasket_check_and_invoke_callback_nolock(
+ gasket_dev, driver_desc->device_close_cb);
+ }
+ }
+
+ dev_dbg(gasket_dev->dev, "New open count (owning tgid %u): %d\n",
+ ownership->owner, ownership->write_open_count);
+ mutex_unlock(&gasket_dev->mutex);
+ return 0;
}
/*
@@ -1702,209 +1356,333 @@ static long gasket_ioctl(struct file *filp, uint cmd, ulong arg)
return gasket_handle_ioctl(filp, cmd, argp);
}
-int gasket_reset(struct gasket_dev *gasket_dev, uint reset_type)
-{
- int ret;
-
- mutex_lock(&gasket_dev->mutex);
- ret = gasket_reset_nolock(gasket_dev, reset_type);
- mutex_unlock(&gasket_dev->mutex);
- return ret;
-}
-EXPORT_SYMBOL(gasket_reset);
+/* File operations for all Gasket devices. */
+static const struct file_operations gasket_file_ops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .mmap = gasket_mmap,
+ .open = gasket_open,
+ .release = gasket_release,
+ .unlocked_ioctl = gasket_ioctl,
+};
-int gasket_reset_nolock(struct gasket_dev *gasket_dev, uint reset_type)
+/* Perform final init and marks the device as active. */
+static int gasket_enable_dev(
+ struct gasket_internal_desc *internal_desc,
+ struct gasket_dev *gasket_dev)
{
+ int tbl_idx;
int ret;
- int i;
- const struct gasket_driver_desc *driver_desc;
+ const struct gasket_driver_desc *driver_desc =
+ internal_desc->driver_desc;
- driver_desc = gasket_dev->internal_desc->driver_desc;
- if (!driver_desc->device_reset_cb)
- return 0;
-
- /* Perform a device reset of the requested type. */
- ret = driver_desc->device_reset_cb(gasket_dev, reset_type);
+ ret = gasket_interrupt_init(
+ gasket_dev, driver_desc->name,
+ driver_desc->interrupt_type, driver_desc->interrupts,
+ driver_desc->num_interrupts, driver_desc->interrupt_pack_width,
+ driver_desc->interrupt_bar_index,
+ driver_desc->wire_interrupt_offsets);
if (ret) {
- dev_dbg(gasket_dev->dev, "Device reset cb returned %d.\n",
- ret);
+ dev_err(gasket_dev->dev,
+ "Critical failure to allocate interrupts: %d\n", ret);
+ gasket_interrupt_cleanup(gasket_dev);
return ret;
}
- /* Reinitialize the page tables and interrupt framework. */
- for (i = 0; i < driver_desc->num_page_tables; ++i)
- gasket_page_table_reset(gasket_dev->page_table[i]);
+ for (tbl_idx = 0; tbl_idx < driver_desc->num_page_tables; tbl_idx++) {
+ dev_dbg(gasket_dev->dev, "Initializing page table %d.\n",
+ tbl_idx);
+ ret = gasket_page_table_init(
+ &gasket_dev->page_table[tbl_idx],
+ &gasket_dev->bar_data[
+ driver_desc->page_table_bar_index],
+ &driver_desc->page_table_configs[tbl_idx],
+ gasket_dev->dev, gasket_dev->pci_dev);
+ if (ret) {
+ dev_err(gasket_dev->dev,
+ "Couldn't init page table %d: %d\n",
+ tbl_idx, ret);
+ return ret;
+ }
+ /*
+ * Make sure that the page table is clear and set to simple
+ * addresses.
+ */
+ gasket_page_table_reset(gasket_dev->page_table[tbl_idx]);
+ }
- ret = gasket_interrupt_reinit(gasket_dev);
+ /*
+ * hardware_revision_cb returns a positive integer (the rev) if
+ * successful.)
+ */
+ ret = check_and_invoke_callback(
+ gasket_dev, driver_desc->hardware_revision_cb);
+ if (ret < 0) {
+ dev_err(gasket_dev->dev,
+ "Error getting hardware revision: %d\n", ret);
+ return ret;
+ }
+ gasket_dev->hardware_revision = ret;
+
+ ret = check_and_invoke_callback(gasket_dev, driver_desc->enable_dev_cb);
if (ret) {
- dev_dbg(gasket_dev->dev, "Unable to reinit interrupts: %d.\n",
+ dev_err(gasket_dev->dev, "Error in enable device cb: %d\n",
ret);
return ret;
}
- /* Get current device health. */
+ /* device_status_cb returns a device status, not an error code. */
gasket_dev->status = gasket_get_hw_status(gasket_dev);
- if (gasket_dev->status == GASKET_STATUS_DEAD) {
- dev_dbg(gasket_dev->dev, "Device reported as dead.\n");
- return -EINVAL;
- }
+ if (gasket_dev->status == GASKET_STATUS_DEAD)
+ dev_err(gasket_dev->dev, "Device reported as unhealthy.\n");
+
+ ret = gasket_add_cdev(
+ &gasket_dev->dev_info, &gasket_file_ops, driver_desc->module);
+ if (ret)
+ return ret;
return 0;
}
-EXPORT_SYMBOL(gasket_reset_nolock);
-gasket_ioctl_permissions_cb_t gasket_get_ioctl_permissions_cb(
- struct gasket_dev *gasket_dev)
+/*
+ * PCI subsystem probe function.
+ *
+ * Called when a Gasket device is found. Allocates device metadata, maps device
+ * memory, and calls gasket_enable_dev to prepare the device for active use.
+ *
+ * Returns 0 if successful and a negative value otherwise.
+ */
+static int gasket_pci_probe(
+ struct pci_dev *pci_dev, const struct pci_device_id *id)
{
- return gasket_dev->internal_desc->driver_desc->ioctl_permissions_cb;
-}
-EXPORT_SYMBOL(gasket_get_ioctl_permissions_cb);
+ int ret;
+ const char *kobj_name = dev_name(&pci_dev->dev);
+ struct gasket_internal_desc *internal_desc;
+ struct gasket_dev *gasket_dev;
+ const struct gasket_driver_desc *driver_desc;
+ struct device *parent;
-static ssize_t gasket_write_mappable_regions(
- char *buf, const struct gasket_driver_desc *driver_desc, int bar_index)
-{
- int i;
- ssize_t written;
- ssize_t total_written = 0;
- ulong min_addr, max_addr;
- struct gasket_bar_desc bar_desc =
- driver_desc->bar_descriptions[bar_index];
+ pr_info("Add Gasket device %s\n", kobj_name);
- if (bar_desc.permissions == GASKET_NOMAP)
- return 0;
- for (i = 0;
- i < bar_desc.num_mappable_regions && total_written < PAGE_SIZE;
- i++) {
- min_addr = bar_desc.mappable_regions[i].start -
- driver_desc->legacy_mmap_address_offset;
- max_addr = bar_desc.mappable_regions[i].start -
- driver_desc->legacy_mmap_address_offset +
- bar_desc.mappable_regions[i].length_bytes;
- written = scnprintf(buf, PAGE_SIZE - total_written,
- "0x%08lx-0x%08lx\n", min_addr, max_addr);
- total_written += written;
- buf += written;
+ mutex_lock(&g_mutex);
+ internal_desc = lookup_internal_desc(pci_dev);
+ mutex_unlock(&g_mutex);
+ if (!internal_desc) {
+ pr_err("PCI probe called for unknown driver type\n");
+ return -ENODEV;
}
- return total_written;
+
+ driver_desc = internal_desc->driver_desc;
+
+ parent = &pci_dev->dev;
+ ret = gasket_alloc_dev(internal_desc, parent, &gasket_dev, kobj_name);
+ if (ret)
+ return ret;
+ gasket_dev->pci_dev = pci_dev_get(pci_dev);
+ if (IS_ERR_OR_NULL(gasket_dev->dev_info.device)) {
+ pr_err("Cannot create %s device %s [ret = %ld]\n",
+ driver_desc->name, gasket_dev->dev_info.name,
+ PTR_ERR(gasket_dev->dev_info.device));
+ ret = -ENODEV;
+ goto fail1;
+ }
+
+ ret = gasket_setup_pci(pci_dev, gasket_dev);
+ if (ret)
+ goto fail2;
+
+ ret = check_and_invoke_callback(gasket_dev, driver_desc->add_dev_cb);
+ if (ret) {
+ dev_err(gasket_dev->dev, "Error in add device cb: %d\n", ret);
+ goto fail2;
+ }
+
+ ret = gasket_sysfs_create_mapping(
+ gasket_dev->dev_info.device, gasket_dev);
+ if (ret)
+ goto fail3;
+
+ /*
+ * Once we've created the mapping structures successfully, attempt to
+ * create a symlink to the pci directory of this object.
+ */
+ ret = sysfs_create_link(&gasket_dev->dev_info.device->kobj,
+ &pci_dev->dev.kobj, dev_name(&pci_dev->dev));
+ if (ret) {
+ dev_err(gasket_dev->dev,
+ "Cannot create sysfs pci link: %d\n", ret);
+ goto fail3;
+ }
+ ret = gasket_sysfs_create_entries(
+ gasket_dev->dev_info.device, gasket_sysfs_generic_attrs);
+ if (ret)
+ goto fail4;
+
+ ret = check_and_invoke_callback(
+ gasket_dev, driver_desc->sysfs_setup_cb);
+ if (ret) {
+ dev_err(gasket_dev->dev, "Error in sysfs setup cb: %d\n", ret);
+ goto fail5;
+ }
+
+ ret = gasket_enable_dev(internal_desc, gasket_dev);
+ if (ret) {
+ pr_err("cannot setup %s device\n", driver_desc->name);
+ gasket_disable_dev(gasket_dev);
+ goto fail5;
+ }
+
+ return 0;
+
+fail5:
+ check_and_invoke_callback(gasket_dev, driver_desc->sysfs_cleanup_cb);
+fail4:
+fail3:
+ gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
+fail2:
+ gasket_cleanup_pci(gasket_dev);
+ check_and_invoke_callback(gasket_dev, driver_desc->remove_dev_cb);
+ device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
+fail1:
+ gasket_free_dev(gasket_dev);
+ return ret;
}
-static ssize_t gasket_sysfs_data_show(
- struct device *device, struct device_attribute *attr, char *buf)
+/*
+ * PCI subsystem remove function.
+ *
+ * Called to remove a Gasket device. Finds the device in the device list and
+ * cleans up metadata.
+ */
+static void gasket_pci_remove(struct pci_dev *pci_dev)
{
- int i, ret = 0;
- ssize_t current_written = 0;
+ int i;
+ struct gasket_internal_desc *internal_desc;
+ struct gasket_dev *gasket_dev = NULL;
const struct gasket_driver_desc *driver_desc;
- struct gasket_dev *gasket_dev;
- struct gasket_sysfs_attribute *gasket_attr;
- const struct gasket_bar_desc *bar_desc;
- enum gasket_sysfs_attribute_type sysfs_type;
-
- gasket_dev = gasket_sysfs_get_device_data(device);
- if (!gasket_dev) {
- dev_err(device, "No sysfs mapping found for device\n");
- return 0;
+ /* Find the device desc. */
+ mutex_lock(&g_mutex);
+ internal_desc = lookup_internal_desc(pci_dev);
+ if (!internal_desc) {
+ mutex_unlock(&g_mutex);
+ return;
}
+ mutex_unlock(&g_mutex);
- gasket_attr = gasket_sysfs_get_attr(device, attr);
- if (!gasket_attr) {
- dev_err(device, "No sysfs attr found for device\n");
- gasket_sysfs_put_device_data(device, gasket_dev);
- return 0;
+ driver_desc = internal_desc->driver_desc;
+
+ /* Now find the specific device */
+ mutex_lock(&internal_desc->mutex);
+ for (i = 0; i < GASKET_DEV_MAX; i++) {
+ if (internal_desc->devs[i] &&
+ internal_desc->devs[i]->pci_dev == pci_dev) {
+ gasket_dev = internal_desc->devs[i];
+ break;
+ }
}
+ mutex_unlock(&internal_desc->mutex);
- driver_desc = gasket_dev->internal_desc->driver_desc;
+ if (!gasket_dev)
+ return;
- sysfs_type =
- (enum gasket_sysfs_attribute_type)gasket_attr->data.attr_type;
- switch (sysfs_type) {
- case ATTR_BAR_OFFSETS:
- for (i = 0; i < GASKET_NUM_BARS; i++) {
- bar_desc = &driver_desc->bar_descriptions[i];
- if (bar_desc->size == 0)
- continue;
- current_written =
- snprintf(buf, PAGE_SIZE - ret, "%d: 0x%lx\n", i,
- (ulong)bar_desc->base);
- buf += current_written;
- ret += current_written;
- }
- break;
- case ATTR_BAR_SIZES:
- for (i = 0; i < GASKET_NUM_BARS; i++) {
- bar_desc = &driver_desc->bar_descriptions[i];
- if (bar_desc->size == 0)
- continue;
- current_written =
- snprintf(buf, PAGE_SIZE - ret, "%d: 0x%lx\n", i,
- (ulong)bar_desc->size);
- buf += current_written;
- ret += current_written;
- }
- break;
- case ATTR_DRIVER_VERSION:
- ret = snprintf(
- buf, PAGE_SIZE, "%s\n",
- gasket_dev->internal_desc->driver_desc->driver_version);
- break;
- case ATTR_FRAMEWORK_VERSION:
- ret = snprintf(
- buf, PAGE_SIZE, "%s\n", GASKET_FRAMEWORK_VERSION);
- break;
- case ATTR_DEVICE_TYPE:
- ret = snprintf(
- buf, PAGE_SIZE, "%s\n",
- gasket_dev->internal_desc->driver_desc->name);
- break;
- case ATTR_HARDWARE_REVISION:
- ret = snprintf(
- buf, PAGE_SIZE, "%d\n", gasket_dev->hardware_revision);
- break;
- case ATTR_PCI_ADDRESS:
- ret = snprintf(buf, PAGE_SIZE, "%s\n", gasket_dev->kobj_name);
- break;
- case ATTR_STATUS:
- ret = snprintf(
- buf, PAGE_SIZE, "%s\n",
- gasket_num_name_lookup(
- gasket_dev->status, gasket_status_name_table));
- break;
- case ATTR_IS_DEVICE_OWNED:
- ret = snprintf(
- buf, PAGE_SIZE, "%d\n",
- gasket_dev->dev_info.ownership.is_owned);
- break;
- case ATTR_DEVICE_OWNER:
- ret = snprintf(
- buf, PAGE_SIZE, "%d\n",
- gasket_dev->dev_info.ownership.owner);
- break;
- case ATTR_WRITE_OPEN_COUNT:
- ret = snprintf(
- buf, PAGE_SIZE, "%d\n",
- gasket_dev->dev_info.ownership.write_open_count);
- break;
- case ATTR_RESET_COUNT:
- ret = snprintf(buf, PAGE_SIZE, "%d\n", gasket_dev->reset_count);
- break;
- case ATTR_USER_MEM_RANGES:
- for (i = 0; i < GASKET_NUM_BARS; ++i) {
- current_written = gasket_write_mappable_regions(
- buf, driver_desc, i);
- buf += current_written;
- ret += current_written;
- }
- break;
- default:
- dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n",
- attr->attr.name);
- ret = 0;
- break;
+ pr_info("remove %s device %s\n", internal_desc->driver_desc->name,
+ gasket_dev->kobj_name);
+
+ gasket_disable_dev(gasket_dev);
+ gasket_cleanup_pci(gasket_dev);
+
+ check_and_invoke_callback(gasket_dev, driver_desc->sysfs_cleanup_cb);
+ gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
+
+ check_and_invoke_callback(gasket_dev, driver_desc->remove_dev_cb);
+
+ device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
+ gasket_free_dev(gasket_dev);
+}
+
+/**
+ * Lookup a name by number in a num_name table.
+ * @num: Number to lookup.
+ * @table: Array of num_name structures, the table for the lookup.
+ *
+ * Description: Searches for num in the table. If found, the
+ * corresponding name is returned; otherwise NULL
+ * is returned.
+ *
+ * The table must have a NULL name pointer at the end.
+ */
+const char *gasket_num_name_lookup(
+ uint num, const struct gasket_num_name *table)
+{
+ uint i = 0;
+
+ while (table[i].snn_name) {
+ if (num == table[i].snn_num)
+ break;
+ ++i;
}
- gasket_sysfs_put_attr(device, gasket_attr);
- gasket_sysfs_put_device_data(device, gasket_dev);
+ return table[i].snn_name;
+}
+EXPORT_SYMBOL(gasket_num_name_lookup);
+
+int gasket_reset(struct gasket_dev *gasket_dev, uint reset_type)
+{
+ int ret;
+
+ mutex_lock(&gasket_dev->mutex);
+ ret = gasket_reset_nolock(gasket_dev, reset_type);
+ mutex_unlock(&gasket_dev->mutex);
return ret;
}
+EXPORT_SYMBOL(gasket_reset);
+
+int gasket_reset_nolock(struct gasket_dev *gasket_dev, uint reset_type)
+{
+ int ret;
+ int i;
+ const struct gasket_driver_desc *driver_desc;
+
+ driver_desc = gasket_dev->internal_desc->driver_desc;
+ if (!driver_desc->device_reset_cb)
+ return 0;
+
+ /* Perform a device reset of the requested type. */
+ ret = driver_desc->device_reset_cb(gasket_dev, reset_type);
+ if (ret) {
+ dev_dbg(gasket_dev->dev, "Device reset cb returned %d.\n",
+ ret);
+ return ret;
+ }
+
+ /* Reinitialize the page tables and interrupt framework. */
+ for (i = 0; i < driver_desc->num_page_tables; ++i)
+ gasket_page_table_reset(gasket_dev->page_table[i]);
+
+ ret = gasket_interrupt_reinit(gasket_dev);
+ if (ret) {
+ dev_dbg(gasket_dev->dev, "Unable to reinit interrupts: %d.\n",
+ ret);
+ return ret;
+ }
+
+ /* Get current device health. */
+ gasket_dev->status = gasket_get_hw_status(gasket_dev);
+ if (gasket_dev->status == GASKET_STATUS_DEAD) {
+ dev_dbg(gasket_dev->dev, "Device reported as dead.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(gasket_reset_nolock);
+
+gasket_ioctl_permissions_cb_t gasket_get_ioctl_permissions_cb(
+ struct gasket_dev *gasket_dev)
+{
+ return gasket_dev->internal_desc->driver_desc->ioctl_permissions_cb;
+}
+EXPORT_SYMBOL(gasket_get_ioctl_permissions_cb);
/* Get the driver structure for a given gasket_dev.
* @dev: pointer to gasket_dev, implementing the requested driver.
@@ -1954,3 +1732,169 @@ int gasket_wait_with_reschedule(
return -ETIMEDOUT;
}
EXPORT_SYMBOL(gasket_wait_with_reschedule);
+
+/* See gasket_core.h for description. */
+int gasket_register_device(const struct gasket_driver_desc *driver_desc)
+{
+ int i, ret;
+ int desc_idx = -1;
+ struct gasket_internal_desc *internal;
+
+ pr_info("Initializing Gasket framework device\n");
+ /* Check for duplicates and find a free slot. */
+ mutex_lock(&g_mutex);
+
+ for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
+ if (g_descs[i].driver_desc == driver_desc) {
+ pr_err("%s driver already loaded/registered\n",
+ driver_desc->name);
+ mutex_unlock(&g_mutex);
+ return -EBUSY;
+ }
+ }
+
+ /* This and the above loop could be combined, but this reads easier. */
+ for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
+ if (!g_descs[i].driver_desc) {
+ g_descs[i].driver_desc = driver_desc;
+ desc_idx = i;
+ break;
+ }
+ }
+ mutex_unlock(&g_mutex);
+
+ pr_info("Loaded %s driver, framework version %s\n",
+ driver_desc->name, GASKET_FRAMEWORK_VERSION);
+
+ if (desc_idx == -1) {
+ pr_err("Too many Gasket drivers loaded: %d\n",
+ GASKET_FRAMEWORK_DESC_MAX);
+ return -EBUSY;
+ }
+
+ /* Internal structure setup. */
+ pr_debug("Performing initial internal structure setup.\n");
+ internal = &g_descs[desc_idx];
+ mutex_init(&internal->mutex);
+ memset(internal->devs, 0, sizeof(struct gasket_dev *) * GASKET_DEV_MAX);
+ memset(&internal->pci, 0, sizeof(internal->pci));
+ internal->pci.name = driver_desc->name;
+ internal->pci.id_table = driver_desc->pci_id_table;
+ internal->pci.probe = gasket_pci_probe;
+ internal->pci.remove = gasket_pci_remove;
+ internal->class =
+ class_create(driver_desc->module, driver_desc->name);
+
+ if (IS_ERR(internal->class)) {
+ pr_err("Cannot register %s class [ret=%ld]\n",
+ driver_desc->name, PTR_ERR(internal->class));
+ ret = PTR_ERR(internal->class);
+ goto unregister_gasket_driver;
+ }
+
+ /*
+ * Not using pci_register_driver() (without underscores), as it
+ * depends on KBUILD_MODNAME, and this is a shared file.
+ */
+ pr_debug("Registering PCI driver.\n");
+ ret = __pci_register_driver(
+ &internal->pci, driver_desc->module, driver_desc->name);
+ if (ret) {
+ pr_err("cannot register pci driver [ret=%d]\n", ret);
+ goto fail1;
+ }
+
+ pr_debug("Registering char driver.\n");
+ ret = register_chrdev_region(
+ MKDEV(driver_desc->major, driver_desc->minor), GASKET_DEV_MAX,
+ driver_desc->name);
+ if (ret) {
+ pr_err("cannot register char driver [ret=%d]\n", ret);
+ goto fail2;
+ }
+
+ pr_info("Driver registered successfully.\n");
+ return 0;
+
+fail2:
+ pci_unregister_driver(&internal->pci);
+
+fail1:
+ class_destroy(internal->class);
+
+unregister_gasket_driver:
+ mutex_lock(&g_mutex);
+ g_descs[desc_idx].driver_desc = NULL;
+ mutex_unlock(&g_mutex);
+ return ret;
+}
+EXPORT_SYMBOL(gasket_register_device);
+
+/* See gasket_core.h for description. */
+void gasket_unregister_device(const struct gasket_driver_desc *driver_desc)
+{
+ int i, desc_idx;
+ struct gasket_internal_desc *internal_desc = NULL;
+
+ mutex_lock(&g_mutex);
+ for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
+ if (g_descs[i].driver_desc == driver_desc) {
+ internal_desc = &g_descs[i];
+ desc_idx = i;
+ break;
+ }
+ }
+ mutex_unlock(&g_mutex);
+
+ if (!internal_desc) {
+ pr_err("request to unregister unknown desc: %s, %d:%d\n",
+ driver_desc->name, driver_desc->major,
+ driver_desc->minor);
+ return;
+ }
+
+ unregister_chrdev_region(
+ MKDEV(driver_desc->major, driver_desc->minor), GASKET_DEV_MAX);
+
+ pci_unregister_driver(&internal_desc->pci);
+
+ class_destroy(internal_desc->class);
+
+ /* Finally, effectively "remove" the driver. */
+ mutex_lock(&g_mutex);
+ g_descs[desc_idx].driver_desc = NULL;
+ mutex_unlock(&g_mutex);
+
+ pr_info("removed %s driver\n", driver_desc->name);
+}
+EXPORT_SYMBOL(gasket_unregister_device);
+
+static int __init gasket_init(void)
+{
+ int i;
+
+ pr_info("Performing one-time init of the Gasket framework.\n");
+ /* Check for duplicates and find a free slot. */
+ mutex_lock(&g_mutex);
+ for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
+ g_descs[i].driver_desc = NULL;
+ mutex_init(&g_descs[i].mutex);
+ }
+
+ gasket_sysfs_init();
+
+ mutex_unlock(&g_mutex);
+ return 0;
+}
+
+static void __exit gasket_exit(void)
+{
+ /* No deinit/dealloc needed at present. */
+ pr_info("Removing Gasket framework module.\n");
+}
+MODULE_DESCRIPTION("Google Gasket driver framework");
+MODULE_VERSION(GASKET_FRAMEWORK_VERSION);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Rob Springer <rspringer@google.com>");
+module_init(gasket_init);
+module_exit(gasket_exit);
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 02/15] staging: gasket: ioctl: remove static function forward declarations
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
2018-07-31 20:24 ` [PATCH 01/15] staging: gasket: core: remove static function forward declarations Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 03/15] staging: gasket: interrupt: " Todd Poynor
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
Remove forward declarations of static functions, move code to avoid
forward references, for kernel style.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/gasket_ioctl.c | 356 ++++++++++++--------------
1 file changed, 168 insertions(+), 188 deletions(-)
diff --git a/drivers/staging/gasket/gasket_ioctl.c b/drivers/staging/gasket/gasket_ioctl.c
index 55bdd7bfac86..134d45a281ac 100644
--- a/drivers/staging/gasket/gasket_ioctl.c
+++ b/drivers/staging/gasket/gasket_ioctl.c
@@ -23,194 +23,6 @@
#define trace_gasket_ioctl_config_coherent_allocator(x, ...)
#endif
-static bool gasket_ioctl_check_permissions(struct file *filp, uint cmd);
-static int gasket_set_event_fd(struct gasket_dev *dev,
- struct gasket_interrupt_eventfd __user *argp);
-static int gasket_read_page_table_size(
- struct gasket_dev *gasket_dev,
- struct gasket_page_table_ioctl __user *argp);
-static int gasket_read_simple_page_table_size(
- struct gasket_dev *gasket_dev,
- struct gasket_page_table_ioctl __user *argp);
-static int gasket_partition_page_table(
- struct gasket_dev *gasket_dev,
- struct gasket_page_table_ioctl __user *argp);
-static int gasket_map_buffers(struct gasket_dev *gasket_dev,
- struct gasket_page_table_ioctl __user *argp);
-static int gasket_unmap_buffers(struct gasket_dev *gasket_dev,
- struct gasket_page_table_ioctl __user *argp);
-static int gasket_config_coherent_allocator(
- struct gasket_dev *gasket_dev,
- struct gasket_coherent_alloc_config_ioctl __user *argp);
-
-/*
- * standard ioctl dispatch function.
- * @filp: File structure pointer describing this node usage session.
- * @cmd: ioctl number to handle.
- * @argp: ioctl-specific data pointer.
- *
- * Standard ioctl dispatcher; forwards operations to individual handlers.
- */
-long gasket_handle_ioctl(struct file *filp, uint cmd, void __user *argp)
-{
- struct gasket_dev *gasket_dev;
- unsigned long arg = (unsigned long)argp;
- gasket_ioctl_permissions_cb_t ioctl_permissions_cb;
- int retval;
-
- gasket_dev = (struct gasket_dev *)filp->private_data;
- trace_gasket_ioctl_entry(gasket_dev->dev_info.name, cmd);
-
- ioctl_permissions_cb = gasket_get_ioctl_permissions_cb(gasket_dev);
- if (ioctl_permissions_cb) {
- retval = ioctl_permissions_cb(filp, cmd, argp);
- if (retval < 0) {
- trace_gasket_ioctl_exit(retval);
- return retval;
- } else if (retval == 0) {
- trace_gasket_ioctl_exit(-EPERM);
- return -EPERM;
- }
- } else if (!gasket_ioctl_check_permissions(filp, cmd)) {
- trace_gasket_ioctl_exit(-EPERM);
- dev_dbg(gasket_dev->dev, "ioctl cmd=%x noperm\n", cmd);
- return -EPERM;
- }
-
- /* Tracing happens in this switch statement for all ioctls with
- * an integer argrument, but ioctls with a struct argument
- * that needs copying and decoding, that tracing is done within
- * the handler call.
- */
- switch (cmd) {
- case GASKET_IOCTL_RESET:
- trace_gasket_ioctl_integer_data(arg);
- retval = gasket_reset(gasket_dev, arg);
- break;
- case GASKET_IOCTL_SET_EVENTFD:
- retval = gasket_set_event_fd(gasket_dev, argp);
- break;
- case GASKET_IOCTL_CLEAR_EVENTFD:
- trace_gasket_ioctl_integer_data(arg);
- retval = gasket_interrupt_clear_eventfd(
- gasket_dev->interrupt_data, (int)arg);
- break;
- case GASKET_IOCTL_PARTITION_PAGE_TABLE:
- trace_gasket_ioctl_integer_data(arg);
- retval = gasket_partition_page_table(gasket_dev, argp);
- break;
- case GASKET_IOCTL_NUMBER_PAGE_TABLES:
- trace_gasket_ioctl_integer_data(gasket_dev->num_page_tables);
- if (copy_to_user(argp, &gasket_dev->num_page_tables,
- sizeof(uint64_t)))
- retval = -EFAULT;
- else
- retval = 0;
- break;
- case GASKET_IOCTL_PAGE_TABLE_SIZE:
- retval = gasket_read_page_table_size(gasket_dev, argp);
- break;
- case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
- retval = gasket_read_simple_page_table_size(gasket_dev, argp);
- break;
- case GASKET_IOCTL_MAP_BUFFER:
- retval = gasket_map_buffers(gasket_dev, argp);
- break;
- case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
- retval = gasket_config_coherent_allocator(gasket_dev, argp);
- break;
- case GASKET_IOCTL_UNMAP_BUFFER:
- retval = gasket_unmap_buffers(gasket_dev, argp);
- break;
- case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
- /* Clear interrupt counts doesn't take an arg, so use 0. */
- trace_gasket_ioctl_integer_data(0);
- retval = gasket_interrupt_reset_counts(gasket_dev);
- break;
- default:
- /* If we don't understand the ioctl, the best we can do is trace
- * the arg.
- */
- trace_gasket_ioctl_integer_data(arg);
- dev_dbg(gasket_dev->dev,
- "Unknown ioctl cmd=0x%x not caught by "
- "gasket_is_supported_ioctl\n",
- cmd);
- retval = -EINVAL;
- break;
- }
-
- trace_gasket_ioctl_exit(retval);
- return retval;
-}
-
-/*
- * Determines if an ioctl is part of the standard Gasket framework.
- * @cmd: The ioctl number to handle.
- *
- * Returns 1 if the ioctl is supported and 0 otherwise.
- */
-long gasket_is_supported_ioctl(uint cmd)
-{
- switch (cmd) {
- case GASKET_IOCTL_RESET:
- case GASKET_IOCTL_SET_EVENTFD:
- case GASKET_IOCTL_CLEAR_EVENTFD:
- case GASKET_IOCTL_PARTITION_PAGE_TABLE:
- case GASKET_IOCTL_NUMBER_PAGE_TABLES:
- case GASKET_IOCTL_PAGE_TABLE_SIZE:
- case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
- case GASKET_IOCTL_MAP_BUFFER:
- case GASKET_IOCTL_UNMAP_BUFFER:
- case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
- case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
- return 1;
- default:
- return 0;
- }
-}
-
-/* Check permissions for Gasket ioctls. */
-static bool gasket_ioctl_check_permissions(struct file *filp, uint cmd)
-{
- bool alive;
- bool read, write;
- struct gasket_dev *gasket_dev = (struct gasket_dev *)filp->private_data;
-
- alive = (gasket_dev->status == GASKET_STATUS_ALIVE);
- if (!alive)
- dev_dbg(gasket_dev->dev, "%s alive %d status %d\n",
- __func__, alive, gasket_dev->status);
-
- read = !!(filp->f_mode & FMODE_READ);
- write = !!(filp->f_mode & FMODE_WRITE);
-
- switch (cmd) {
- case GASKET_IOCTL_RESET:
- case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
- return write;
-
- case GASKET_IOCTL_PAGE_TABLE_SIZE:
- case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
- case GASKET_IOCTL_NUMBER_PAGE_TABLES:
- return read;
-
- case GASKET_IOCTL_PARTITION_PAGE_TABLE:
- case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
- return alive && write;
-
- case GASKET_IOCTL_MAP_BUFFER:
- case GASKET_IOCTL_UNMAP_BUFFER:
- return alive && write;
-
- case GASKET_IOCTL_CLEAR_EVENTFD:
- case GASKET_IOCTL_SET_EVENTFD:
- return alive && write;
- }
-
- return false; /* unknown permissions */
-}
-
/* Associate an eventfd with an interrupt. */
static int gasket_set_event_fd(struct gasket_dev *gasket_dev,
struct gasket_interrupt_eventfd __user *argp)
@@ -410,3 +222,171 @@ static int gasket_config_coherent_allocator(
return 0;
}
+
+/* Check permissions for Gasket ioctls. */
+static bool gasket_ioctl_check_permissions(struct file *filp, uint cmd)
+{
+ bool alive;
+ bool read, write;
+ struct gasket_dev *gasket_dev = (struct gasket_dev *)filp->private_data;
+
+ alive = (gasket_dev->status == GASKET_STATUS_ALIVE);
+ if (!alive)
+ dev_dbg(gasket_dev->dev, "%s alive %d status %d\n",
+ __func__, alive, gasket_dev->status);
+
+ read = !!(filp->f_mode & FMODE_READ);
+ write = !!(filp->f_mode & FMODE_WRITE);
+
+ switch (cmd) {
+ case GASKET_IOCTL_RESET:
+ case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
+ return write;
+
+ case GASKET_IOCTL_PAGE_TABLE_SIZE:
+ case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
+ case GASKET_IOCTL_NUMBER_PAGE_TABLES:
+ return read;
+
+ case GASKET_IOCTL_PARTITION_PAGE_TABLE:
+ case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
+ return alive && write;
+
+ case GASKET_IOCTL_MAP_BUFFER:
+ case GASKET_IOCTL_UNMAP_BUFFER:
+ return alive && write;
+
+ case GASKET_IOCTL_CLEAR_EVENTFD:
+ case GASKET_IOCTL_SET_EVENTFD:
+ return alive && write;
+ }
+
+ return false; /* unknown permissions */
+}
+
+/*
+ * standard ioctl dispatch function.
+ * @filp: File structure pointer describing this node usage session.
+ * @cmd: ioctl number to handle.
+ * @argp: ioctl-specific data pointer.
+ *
+ * Standard ioctl dispatcher; forwards operations to individual handlers.
+ */
+long gasket_handle_ioctl(struct file *filp, uint cmd, void __user *argp)
+{
+ struct gasket_dev *gasket_dev;
+ unsigned long arg = (unsigned long)argp;
+ gasket_ioctl_permissions_cb_t ioctl_permissions_cb;
+ int retval;
+
+ gasket_dev = (struct gasket_dev *)filp->private_data;
+ trace_gasket_ioctl_entry(gasket_dev->dev_info.name, cmd);
+
+ ioctl_permissions_cb = gasket_get_ioctl_permissions_cb(gasket_dev);
+ if (ioctl_permissions_cb) {
+ retval = ioctl_permissions_cb(filp, cmd, argp);
+ if (retval < 0) {
+ trace_gasket_ioctl_exit(retval);
+ return retval;
+ } else if (retval == 0) {
+ trace_gasket_ioctl_exit(-EPERM);
+ return -EPERM;
+ }
+ } else if (!gasket_ioctl_check_permissions(filp, cmd)) {
+ trace_gasket_ioctl_exit(-EPERM);
+ dev_dbg(gasket_dev->dev, "ioctl cmd=%x noperm\n", cmd);
+ return -EPERM;
+ }
+
+ /* Tracing happens in this switch statement for all ioctls with
+ * an integer argrument, but ioctls with a struct argument
+ * that needs copying and decoding, that tracing is done within
+ * the handler call.
+ */
+ switch (cmd) {
+ case GASKET_IOCTL_RESET:
+ trace_gasket_ioctl_integer_data(arg);
+ retval = gasket_reset(gasket_dev, arg);
+ break;
+ case GASKET_IOCTL_SET_EVENTFD:
+ retval = gasket_set_event_fd(gasket_dev, argp);
+ break;
+ case GASKET_IOCTL_CLEAR_EVENTFD:
+ trace_gasket_ioctl_integer_data(arg);
+ retval = gasket_interrupt_clear_eventfd(
+ gasket_dev->interrupt_data, (int)arg);
+ break;
+ case GASKET_IOCTL_PARTITION_PAGE_TABLE:
+ trace_gasket_ioctl_integer_data(arg);
+ retval = gasket_partition_page_table(gasket_dev, argp);
+ break;
+ case GASKET_IOCTL_NUMBER_PAGE_TABLES:
+ trace_gasket_ioctl_integer_data(gasket_dev->num_page_tables);
+ if (copy_to_user(argp, &gasket_dev->num_page_tables,
+ sizeof(uint64_t)))
+ retval = -EFAULT;
+ else
+ retval = 0;
+ break;
+ case GASKET_IOCTL_PAGE_TABLE_SIZE:
+ retval = gasket_read_page_table_size(gasket_dev, argp);
+ break;
+ case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
+ retval = gasket_read_simple_page_table_size(gasket_dev, argp);
+ break;
+ case GASKET_IOCTL_MAP_BUFFER:
+ retval = gasket_map_buffers(gasket_dev, argp);
+ break;
+ case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
+ retval = gasket_config_coherent_allocator(gasket_dev, argp);
+ break;
+ case GASKET_IOCTL_UNMAP_BUFFER:
+ retval = gasket_unmap_buffers(gasket_dev, argp);
+ break;
+ case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
+ /* Clear interrupt counts doesn't take an arg, so use 0. */
+ trace_gasket_ioctl_integer_data(0);
+ retval = gasket_interrupt_reset_counts(gasket_dev);
+ break;
+ default:
+ /* If we don't understand the ioctl, the best we can do is trace
+ * the arg.
+ */
+ trace_gasket_ioctl_integer_data(arg);
+ dev_dbg(gasket_dev->dev,
+ "Unknown ioctl cmd=0x%x not caught by "
+ "gasket_is_supported_ioctl\n",
+ cmd);
+ retval = -EINVAL;
+ break;
+ }
+
+ trace_gasket_ioctl_exit(retval);
+ return retval;
+}
+
+/*
+ * Determines if an ioctl is part of the standard Gasket framework.
+ * @cmd: The ioctl number to handle.
+ *
+ * Returns 1 if the ioctl is supported and 0 otherwise.
+ */
+long gasket_is_supported_ioctl(uint cmd)
+{
+ switch (cmd) {
+ case GASKET_IOCTL_RESET:
+ case GASKET_IOCTL_SET_EVENTFD:
+ case GASKET_IOCTL_CLEAR_EVENTFD:
+ case GASKET_IOCTL_PARTITION_PAGE_TABLE:
+ case GASKET_IOCTL_NUMBER_PAGE_TABLES:
+ case GASKET_IOCTL_PAGE_TABLE_SIZE:
+ case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
+ case GASKET_IOCTL_MAP_BUFFER:
+ case GASKET_IOCTL_UNMAP_BUFFER:
+ case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
+ case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
+ return 1;
+ default:
+ return 0;
+ }
+}
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 03/15] staging: gasket: interrupt: remove static function forward declarations
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
2018-07-31 20:24 ` [PATCH 01/15] staging: gasket: core: remove static function forward declarations Todd Poynor
2018-07-31 20:24 ` [PATCH 02/15] staging: gasket: ioctl: " Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 04/15] staging: gasket: pg tbl: " Todd Poynor
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
Remove forward declarations of static functions, move code to avoid
forward references, for kernel style.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/gasket_interrupt.c | 499 +++++++++++-----------
1 file changed, 242 insertions(+), 257 deletions(-)
diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c
index 27fde991edc6..3079b59b122b 100644
--- a/drivers/staging/gasket/gasket_interrupt.c
+++ b/drivers/staging/gasket/gasket_interrupt.c
@@ -70,32 +70,259 @@ struct gasket_interrupt_data {
int irq;
};
-/* Function definitions. */
-static ssize_t interrupt_sysfs_show(
- struct device *device, struct device_attribute *attr, char *buf);
-
-static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id);
-
/* Structures to display interrupt counts in sysfs. */
enum interrupt_sysfs_attribute_type {
ATTR_INTERRUPT_COUNTS,
};
+/* Set up device registers for interrupt handling. */
+static void gasket_interrupt_setup(struct gasket_dev *gasket_dev)
+{
+ int i;
+ int pack_shift;
+ ulong mask;
+ ulong value;
+ struct gasket_interrupt_data *interrupt_data =
+ gasket_dev->interrupt_data;
+
+ if (!interrupt_data) {
+ dev_dbg(gasket_dev->dev, "Interrupt data is not initialized\n");
+ return;
+ }
+
+ dev_dbg(gasket_dev->dev, "Running interrupt setup\n");
+
+ if (interrupt_data->type == PLATFORM_WIRE ||
+ interrupt_data->type == PCI_MSI) {
+ /* Nothing needs to be done for platform or PCI devices. */
+ return;
+ }
+
+ if (interrupt_data->type != PCI_MSIX) {
+ dev_dbg(gasket_dev->dev,
+ "Cannot handle unsupported interrupt type %d\n",
+ interrupt_data->type);
+ return;
+ }
+
+ /* Setup the MSIX table. */
+
+ for (i = 0; i < interrupt_data->num_interrupts; i++) {
+ /*
+ * If the interrupt is not packed, we can write the index into
+ * the register directly. If not, we need to deal with a read-
+ * modify-write and shift based on the packing index.
+ */
+ dev_dbg(gasket_dev->dev,
+ "Setting up interrupt index %d with index 0x%llx and "
+ "packing %d\n",
+ interrupt_data->interrupts[i].index,
+ interrupt_data->interrupts[i].reg,
+ interrupt_data->interrupts[i].packing);
+ if (interrupt_data->interrupts[i].packing == UNPACKED) {
+ value = interrupt_data->interrupts[i].index;
+ } else {
+ switch (interrupt_data->interrupts[i].packing) {
+ case PACK_0:
+ pack_shift = 0;
+ break;
+ case PACK_1:
+ pack_shift = interrupt_data->pack_width;
+ break;
+ case PACK_2:
+ pack_shift = 2 * interrupt_data->pack_width;
+ break;
+ case PACK_3:
+ pack_shift = 3 * interrupt_data->pack_width;
+ break;
+ default:
+ dev_dbg(gasket_dev->dev,
+ "Found interrupt description with "
+ "unknown enum %d\n",
+ interrupt_data->interrupts[i].packing);
+ return;
+ }
+
+ mask = ~(0xFFFF << pack_shift);
+ value = gasket_dev_read_64(
+ gasket_dev,
+ interrupt_data->interrupt_bar_index,
+ interrupt_data->interrupts[i].reg) &
+ mask;
+ value |= interrupt_data->interrupts[i].index
+ << pack_shift;
+ }
+ gasket_dev_write_64(gasket_dev, value,
+ interrupt_data->interrupt_bar_index,
+ interrupt_data->interrupts[i].reg);
+ }
+}
+
+static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id)
+{
+ struct eventfd_ctx *ctx;
+ struct gasket_interrupt_data *interrupt_data = dev_id;
+ int interrupt = -1;
+ int i;
+
+ /* If this linear lookup is a problem, we can maintain a map/hash. */
+ for (i = 0; i < interrupt_data->num_interrupts; i++) {
+ if (interrupt_data->msix_entries[i].vector == irq) {
+ interrupt = interrupt_data->msix_entries[i].entry;
+ break;
+ }
+ }
+ if (interrupt == -1) {
+ pr_err("Received unknown irq %d\n", irq);
+ return IRQ_HANDLED;
+ }
+ trace_gasket_interrupt_event(interrupt_data->name, interrupt);
+
+ ctx = interrupt_data->eventfd_ctxs[interrupt];
+ if (ctx)
+ eventfd_signal(ctx, 1);
+
+ ++(interrupt_data->interrupt_counts[interrupt]);
+
+ return IRQ_HANDLED;
+}
+
+static int gasket_interrupt_msix_init(
+ struct gasket_interrupt_data *interrupt_data)
+{
+ int ret = 1;
+ int i;
+
+ for (i = 0; i < interrupt_data->num_interrupts; i++) {
+ interrupt_data->msix_entries[i].entry = i;
+ interrupt_data->msix_entries[i].vector = 0;
+ interrupt_data->eventfd_ctxs[i] = NULL;
+ }
+
+ /* Retry MSIX_RETRY_COUNT times if not enough IRQs are available. */
+ for (i = 0; i < MSIX_RETRY_COUNT && ret > 0; i++)
+ ret = pci_enable_msix_exact(interrupt_data->pci_dev,
+ interrupt_data->msix_entries,
+ interrupt_data->num_interrupts);
+
+ if (ret)
+ return ret > 0 ? -EBUSY : ret;
+ interrupt_data->msix_configured = 1;
+
+ for (i = 0; i < interrupt_data->num_interrupts; i++) {
+ ret = request_irq(
+ interrupt_data->msix_entries[i].vector,
+ gasket_msix_interrupt_handler, 0, interrupt_data->name,
+ interrupt_data);
+
+ if (ret) {
+ dev_err(&interrupt_data->pci_dev->dev,
+ "Cannot get IRQ for interrupt %d, vector %d; "
+ "%d\n",
+ i, interrupt_data->msix_entries[i].vector, ret);
+ return ret;
+ }
+
+ interrupt_data->num_configured++;
+ }
+
+ return 0;
+}
+
+/*
+ * On QCM DragonBoard, we exit gasket_interrupt_msix_init() and kernel interrupt
+ * setup code with MSIX vectors masked. This is wrong because nothing else in
+ * the driver will normally touch the MSIX vectors.
+ *
+ * As a temporary hack, force unmasking there.
+ *
+ * TODO: Figure out why QCM kernel doesn't unmask the MSIX vectors, after
+ * gasket_interrupt_msix_init(), and remove this code.
+ */
+static void force_msix_interrupt_unmasking(struct gasket_dev *gasket_dev)
+{
+ int i;
+#define MSIX_VECTOR_SIZE 16
+#define MSIX_MASK_BIT_OFFSET 12
+#define APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE 0x46800
+ for (i = 0; i < gasket_dev->interrupt_data->num_configured; i++) {
+ /* Check if the MSIX vector is unmasked */
+ ulong location = APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE +
+ MSIX_MASK_BIT_OFFSET + i * MSIX_VECTOR_SIZE;
+ u32 mask =
+ gasket_dev_read_32(
+ gasket_dev,
+ gasket_dev->interrupt_data->interrupt_bar_index,
+ location);
+ if (!(mask & 1))
+ continue;
+ /* Unmask the msix vector (clear 32 bits) */
+ gasket_dev_write_32(
+ gasket_dev, 0,
+ gasket_dev->interrupt_data->interrupt_bar_index,
+ location);
+ }
+#undef MSIX_VECTOR_SIZE
+#undef MSIX_MASK_BIT_OFFSET
+#undef APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE
+}
+
+static ssize_t interrupt_sysfs_show(
+ struct device *device, struct device_attribute *attr, char *buf)
+{
+ int i, ret;
+ ssize_t written = 0, total_written = 0;
+ struct gasket_interrupt_data *interrupt_data;
+ struct gasket_dev *gasket_dev;
+ struct gasket_sysfs_attribute *gasket_attr;
+ enum interrupt_sysfs_attribute_type sysfs_type;
+
+ gasket_dev = gasket_sysfs_get_device_data(device);
+ if (!gasket_dev) {
+ dev_dbg(device, "No sysfs mapping found for device\n");
+ return 0;
+ }
+
+ gasket_attr = gasket_sysfs_get_attr(device, attr);
+ if (!gasket_attr) {
+ dev_dbg(device, "No sysfs attr data found for device\n");
+ gasket_sysfs_put_device_data(device, gasket_dev);
+ return 0;
+ }
+
+ sysfs_type = (enum interrupt_sysfs_attribute_type)
+ gasket_attr->data.attr_type;
+ interrupt_data = gasket_dev->interrupt_data;
+ switch (sysfs_type) {
+ case ATTR_INTERRUPT_COUNTS:
+ for (i = 0; i < interrupt_data->num_interrupts; ++i) {
+ written =
+ scnprintf(buf, PAGE_SIZE - total_written,
+ "0x%02x: %ld\n", i,
+ interrupt_data->interrupt_counts[i]);
+ total_written += written;
+ buf += written;
+ }
+ ret = total_written;
+ break;
+ default:
+ dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n",
+ attr->attr.name);
+ ret = 0;
+ break;
+ }
+
+ gasket_sysfs_put_attr(device, gasket_attr);
+ gasket_sysfs_put_device_data(device, gasket_dev);
+ return ret;
+}
+
static struct gasket_sysfs_attribute interrupt_sysfs_attrs[] = {
GASKET_SYSFS_RO(
interrupt_counts, interrupt_sysfs_show, ATTR_INTERRUPT_COUNTS),
GASKET_END_OF_ATTR_ARRAY,
};
-static void gasket_interrupt_setup(struct gasket_dev *gasket_dev);
-
-/* MSIX init and cleanup. */
-static int gasket_interrupt_msix_init(
- struct gasket_interrupt_data *interrupt_data);
-static void gasket_interrupt_msix_cleanup(
- struct gasket_interrupt_data *interrupt_data);
-static void force_msix_interrupt_unmasking(struct gasket_dev *gasket_dev);
-
int gasket_interrupt_init(
struct gasket_dev *gasket_dev, const char *name, int type,
const struct gasket_interrupt_desc *interrupts,
@@ -181,48 +408,6 @@ int gasket_interrupt_init(
return 0;
}
-static int gasket_interrupt_msix_init(
- struct gasket_interrupt_data *interrupt_data)
-{
- int ret = 1;
- int i;
-
- for (i = 0; i < interrupt_data->num_interrupts; i++) {
- interrupt_data->msix_entries[i].entry = i;
- interrupt_data->msix_entries[i].vector = 0;
- interrupt_data->eventfd_ctxs[i] = NULL;
- }
-
- /* Retry MSIX_RETRY_COUNT times if not enough IRQs are available. */
- for (i = 0; i < MSIX_RETRY_COUNT && ret > 0; i++)
- ret = pci_enable_msix_exact(interrupt_data->pci_dev,
- interrupt_data->msix_entries,
- interrupt_data->num_interrupts);
-
- if (ret)
- return ret > 0 ? -EBUSY : ret;
- interrupt_data->msix_configured = 1;
-
- for (i = 0; i < interrupt_data->num_interrupts; i++) {
- ret = request_irq(
- interrupt_data->msix_entries[i].vector,
- gasket_msix_interrupt_handler, 0, interrupt_data->name,
- interrupt_data);
-
- if (ret) {
- dev_err(&interrupt_data->pci_dev->dev,
- "Cannot get IRQ for interrupt %d, vector %d; "
- "%d\n",
- i, interrupt_data->msix_entries[i].vector, ret);
- return ret;
- }
-
- interrupt_data->num_configured++;
- }
-
- return 0;
-}
-
static void gasket_interrupt_msix_cleanup(
struct gasket_interrupt_data *interrupt_data)
{
@@ -238,44 +423,6 @@ static void gasket_interrupt_msix_cleanup(
interrupt_data->msix_configured = 0;
}
-/*
- * On QCM DragonBoard, we exit gasket_interrupt_msix_init() and kernel interrupt
- * setup code with MSIX vectors masked. This is wrong because nothing else in
- * the driver will normally touch the MSIX vectors.
- *
- * As a temporary hack, force unmasking there.
- *
- * TODO: Figure out why QCM kernel doesn't unmask the MSIX vectors, after
- * gasket_interrupt_msix_init(), and remove this code.
- */
-static void force_msix_interrupt_unmasking(struct gasket_dev *gasket_dev)
-{
- int i;
-#define MSIX_VECTOR_SIZE 16
-#define MSIX_MASK_BIT_OFFSET 12
-#define APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE 0x46800
- for (i = 0; i < gasket_dev->interrupt_data->num_configured; i++) {
- /* Check if the MSIX vector is unmasked */
- ulong location = APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE +
- MSIX_MASK_BIT_OFFSET + i * MSIX_VECTOR_SIZE;
- u32 mask =
- gasket_dev_read_32(
- gasket_dev,
- gasket_dev->interrupt_data->interrupt_bar_index,
- location);
- if (!(mask & 1))
- continue;
- /* Unmask the msix vector (clear 32 bits) */
- gasket_dev_write_32(
- gasket_dev, 0,
- gasket_dev->interrupt_data->interrupt_bar_index,
- location);
- }
-#undef MSIX_VECTOR_SIZE
-#undef MSIX_MASK_BIT_OFFSET
-#undef APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE
-}
-
int gasket_interrupt_reinit(struct gasket_dev *gasket_dev)
{
int ret;
@@ -327,89 +474,6 @@ int gasket_interrupt_reset_counts(struct gasket_dev *gasket_dev)
return 0;
}
-/* Set up device registers for interrupt handling. */
-static void gasket_interrupt_setup(struct gasket_dev *gasket_dev)
-{
- int i;
- int pack_shift;
- ulong mask;
- ulong value;
- struct gasket_interrupt_data *interrupt_data =
- gasket_dev->interrupt_data;
-
- if (!interrupt_data) {
- dev_dbg(gasket_dev->dev, "Interrupt data is not initialized\n");
- return;
- }
-
- dev_dbg(gasket_dev->dev, "Running interrupt setup\n");
-
- if (interrupt_data->type == PLATFORM_WIRE ||
- interrupt_data->type == PCI_MSI) {
- /* Nothing needs to be done for platform or PCI devices. */
- return;
- }
-
- if (interrupt_data->type != PCI_MSIX) {
- dev_dbg(gasket_dev->dev,
- "Cannot handle unsupported interrupt type %d\n",
- interrupt_data->type);
- return;
- }
-
- /* Setup the MSIX table. */
-
- for (i = 0; i < interrupt_data->num_interrupts; i++) {
- /*
- * If the interrupt is not packed, we can write the index into
- * the register directly. If not, we need to deal with a read-
- * modify-write and shift based on the packing index.
- */
- dev_dbg(gasket_dev->dev,
- "Setting up interrupt index %d with index 0x%llx and "
- "packing %d\n",
- interrupt_data->interrupts[i].index,
- interrupt_data->interrupts[i].reg,
- interrupt_data->interrupts[i].packing);
- if (interrupt_data->interrupts[i].packing == UNPACKED) {
- value = interrupt_data->interrupts[i].index;
- } else {
- switch (interrupt_data->interrupts[i].packing) {
- case PACK_0:
- pack_shift = 0;
- break;
- case PACK_1:
- pack_shift = interrupt_data->pack_width;
- break;
- case PACK_2:
- pack_shift = 2 * interrupt_data->pack_width;
- break;
- case PACK_3:
- pack_shift = 3 * interrupt_data->pack_width;
- break;
- default:
- dev_dbg(gasket_dev->dev,
- "Found interrupt description with "
- "unknown enum %d\n",
- interrupt_data->interrupts[i].packing);
- return;
- }
-
- mask = ~(0xFFFF << pack_shift);
- value = gasket_dev_read_64(
- gasket_dev,
- interrupt_data->interrupt_bar_index,
- interrupt_data->interrupts[i].reg) &
- mask;
- value |= interrupt_data->interrupts[i].index
- << pack_shift;
- }
- gasket_dev_write_64(gasket_dev, value,
- interrupt_data->interrupt_bar_index,
- interrupt_data->interrupts[i].reg);
- }
-}
-
/* See gasket_interrupt.h for description. */
void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev)
{
@@ -489,82 +553,3 @@ int gasket_interrupt_clear_eventfd(
interrupt_data->eventfd_ctxs[interrupt] = NULL;
return 0;
}
-
-static ssize_t interrupt_sysfs_show(
- struct device *device, struct device_attribute *attr, char *buf)
-{
- int i, ret;
- ssize_t written = 0, total_written = 0;
- struct gasket_interrupt_data *interrupt_data;
- struct gasket_dev *gasket_dev;
- struct gasket_sysfs_attribute *gasket_attr;
- enum interrupt_sysfs_attribute_type sysfs_type;
-
- gasket_dev = gasket_sysfs_get_device_data(device);
- if (!gasket_dev) {
- dev_dbg(device, "No sysfs mapping found for device\n");
- return 0;
- }
-
- gasket_attr = gasket_sysfs_get_attr(device, attr);
- if (!gasket_attr) {
- dev_dbg(device, "No sysfs attr data found for device\n");
- gasket_sysfs_put_device_data(device, gasket_dev);
- return 0;
- }
-
- sysfs_type = (enum interrupt_sysfs_attribute_type)
- gasket_attr->data.attr_type;
- interrupt_data = gasket_dev->interrupt_data;
- switch (sysfs_type) {
- case ATTR_INTERRUPT_COUNTS:
- for (i = 0; i < interrupt_data->num_interrupts; ++i) {
- written =
- scnprintf(buf, PAGE_SIZE - total_written,
- "0x%02x: %ld\n", i,
- interrupt_data->interrupt_counts[i]);
- total_written += written;
- buf += written;
- }
- ret = total_written;
- break;
- default:
- dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n",
- attr->attr.name);
- ret = 0;
- break;
- }
-
- gasket_sysfs_put_attr(device, gasket_attr);
- gasket_sysfs_put_device_data(device, gasket_dev);
- return ret;
-}
-
-static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id)
-{
- struct eventfd_ctx *ctx;
- struct gasket_interrupt_data *interrupt_data = dev_id;
- int interrupt = -1;
- int i;
-
- /* If this linear lookup is a problem, we can maintain a map/hash. */
- for (i = 0; i < interrupt_data->num_interrupts; i++) {
- if (interrupt_data->msix_entries[i].vector == irq) {
- interrupt = interrupt_data->msix_entries[i].entry;
- break;
- }
- }
- if (interrupt == -1) {
- pr_err("Received unknown irq %d\n", irq);
- return IRQ_HANDLED;
- }
- trace_gasket_interrupt_event(interrupt_data->name, interrupt);
-
- ctx = interrupt_data->eventfd_ctxs[interrupt];
- if (ctx)
- eventfd_signal(ctx, 1);
-
- ++(interrupt_data->interrupt_counts[interrupt]);
-
- return IRQ_HANDLED;
-}
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 04/15] staging: gasket: pg tbl: remove static function forward declarations
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
` (2 preceding siblings ...)
2018-07-31 20:24 ` [PATCH 03/15] staging: gasket: interrupt: " Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 05/15] staging: gasket: TODO: remove entry for static function declarations Todd Poynor
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
Remove forward declarations of static functions, move code to avoid
forward references, for kernel style.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/gasket_page_table.c | 1433 ++++++++++----------
1 file changed, 684 insertions(+), 749 deletions(-)
diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c
index b42f6637b909..aa036b2e8193 100644
--- a/drivers/staging/gasket/gasket_page_table.c
+++ b/drivers/staging/gasket/gasket_page_table.c
@@ -214,71 +214,6 @@ struct gasket_page_table {
struct gasket_coherent_page_entry *coherent_pages;
};
-/* Mapping declarations */
-static int gasket_map_simple_pages(
- struct gasket_page_table *pg_tbl, ulong host_addr,
- ulong dev_addr, uint num_pages);
-static int gasket_map_extended_pages(
- struct gasket_page_table *pg_tbl, ulong host_addr,
- ulong dev_addr, uint num_pages);
-static int gasket_perform_mapping(
- struct gasket_page_table *pg_tbl,
- struct gasket_page_table_entry *pte_base, u64 __iomem *att_base,
- ulong host_addr, uint num_pages, int is_simple_mapping);
-
-static int gasket_alloc_simple_entries(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages);
-static int gasket_alloc_extended_entries(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_entries);
-static int gasket_alloc_extended_subtable(
- struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *pte,
- u64 __iomem *att_reg);
-
-/* Unmapping declarations */
-static void gasket_page_table_unmap_nolock(
- struct gasket_page_table *pg_tbl, ulong start_addr, uint num_pages);
-static void gasket_page_table_unmap_all_nolock(
- struct gasket_page_table *pg_tbl);
-static void gasket_unmap_simple_pages(
- struct gasket_page_table *pg_tbl, ulong start_addr, uint num_pages);
-static void gasket_unmap_extended_pages(
- struct gasket_page_table *pg_tbl, ulong start_addr, uint num_pages);
-static void gasket_perform_unmapping(
- struct gasket_page_table *pg_tbl,
- struct gasket_page_table_entry *pte_base, u64 __iomem *att_base,
- uint num_pages, int is_simple_mapping);
-
-static void gasket_free_extended_subtable(
- struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *pte,
- u64 __iomem *att_reg);
-static bool gasket_release_page(struct page *page);
-
-/* Other/utility declarations */
-static inline bool gasket_addr_is_simple(
- struct gasket_page_table *pg_tbl, ulong addr);
-static bool gasket_is_simple_dev_addr_bad(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages);
-static bool gasket_is_extended_dev_addr_bad(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages);
-static bool gasket_is_pte_range_free(
- struct gasket_page_table_entry *pte, uint num_entries);
-static void gasket_page_table_garbage_collect_nolock(
- struct gasket_page_table *pg_tbl);
-
-/* Address format declarations */
-static ulong gasket_components_to_dev_address(
- struct gasket_page_table *pg_tbl, int is_simple, uint page_index,
- uint offset);
-static int gasket_simple_page_idx(
- struct gasket_page_table *pg_tbl, ulong dev_addr);
-static ulong gasket_extended_lvl0_page_idx(
- struct gasket_page_table *pg_tbl, ulong dev_addr);
-static ulong gasket_extended_lvl1_page_idx(
- struct gasket_page_table *pg_tbl, ulong dev_addr);
-
-static int is_coherent(struct gasket_page_table *pg_tbl, ulong host_addr);
-
-/* Public/exported functions */
/* See gasket_page_table.h for description. */
int gasket_page_table_init(
struct gasket_page_table **ppg_tbl,
@@ -353,6 +288,85 @@ int gasket_page_table_init(
return 0;
}
+/*
+ * Check if a range of PTEs is free.
+ * The page table mutex must be held by the caller.
+ */
+static bool gasket_is_pte_range_free(
+ struct gasket_page_table_entry *ptes, uint num_entries)
+{
+ int i;
+
+ for (i = 0; i < num_entries; i++) {
+ if (ptes[i].status != PTE_FREE)
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Free a second level page [sub]table.
+ * The page table mutex must be held before this call.
+ */
+static void gasket_free_extended_subtable(
+ struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *pte,
+ u64 __iomem *slot)
+{
+ /* Release the page table from the driver */
+ pte->status = PTE_FREE;
+
+ /* Release the page table from the device */
+ writeq(0, slot);
+ /* Force sync around the address release. */
+ mb();
+
+ if (pte->dma_addr)
+ dma_unmap_page(pg_tbl->device, pte->dma_addr, PAGE_SIZE,
+ DMA_BIDIRECTIONAL);
+
+ vfree(pte->sublevel);
+
+ if (pte->page)
+ free_page((ulong)page_address(pte->page));
+
+ memset(pte, 0, sizeof(struct gasket_page_table_entry));
+}
+
+/*
+ * Actually perform collection.
+ * The page table mutex must be held by the caller.
+ */
+static void gasket_page_table_garbage_collect_nolock(
+ struct gasket_page_table *pg_tbl)
+{
+ struct gasket_page_table_entry *pte;
+ u64 __iomem *slot;
+
+ /* XXX FIX ME XXX -- more efficient to keep a usage count */
+ /* rather than scanning the second level page tables */
+
+ for (pte = pg_tbl->entries + pg_tbl->num_simple_entries,
+ slot = pg_tbl->base_slot + pg_tbl->num_simple_entries;
+ pte < pg_tbl->entries + pg_tbl->config.total_entries;
+ pte++, slot++) {
+ if (pte->status == PTE_INUSE) {
+ if (gasket_is_pte_range_free(
+ pte->sublevel, GASKET_PAGES_PER_SUBTABLE))
+ gasket_free_extended_subtable(
+ pg_tbl, pte, slot);
+ }
+ }
+}
+
+/* See gasket_page_table.h for description. */
+void gasket_page_table_garbage_collect(struct gasket_page_table *pg_tbl)
+{
+ mutex_lock(&pg_tbl->mutex);
+ gasket_page_table_garbage_collect_nolock(pg_tbl);
+ mutex_unlock(&pg_tbl->mutex);
+}
+
/* See gasket_page_table.h for description. */
void gasket_page_table_cleanup(struct gasket_page_table *pg_tbl)
{
@@ -404,500 +418,467 @@ int gasket_page_table_partition(
EXPORT_SYMBOL(gasket_page_table_partition);
/*
- * See gasket_page_table.h for general description.
- *
- * gasket_page_table_map calls either gasket_map_simple_pages() or
- * gasket_map_extended_pages() to actually perform the mapping.
+ * Return whether a host buffer was mapped as coherent memory.
*
- * The page table mutex is held for the entire operation.
+ * A Gasket page_table currently support one contiguous dma range, mapped to one
+ * contiguous virtual memory range. Check if the host_addr is within that range.
*/
-int gasket_page_table_map(
- struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr,
- uint num_pages)
+static int is_coherent(struct gasket_page_table *pg_tbl, ulong host_addr)
{
- int ret;
+ u64 min, max;
- if (!num_pages)
+ /* whether the host address is within user virt range */
+ if (!pg_tbl->coherent_pages)
return 0;
- mutex_lock(&pg_tbl->mutex);
-
- if (gasket_addr_is_simple(pg_tbl, dev_addr)) {
- ret = gasket_map_simple_pages(
- pg_tbl, host_addr, dev_addr, num_pages);
- } else {
- ret = gasket_map_extended_pages(
- pg_tbl, host_addr, dev_addr, num_pages);
- }
-
- mutex_unlock(&pg_tbl->mutex);
+ min = (u64)pg_tbl->coherent_pages[0].user_virt;
+ max = min + PAGE_SIZE * pg_tbl->num_coherent_pages;
- dev_dbg(pg_tbl->device,
- "%s done: ha %llx daddr %llx num %d, ret %d\n",
- __func__, (unsigned long long)host_addr,
- (unsigned long long)dev_addr, num_pages, ret);
- return ret;
+ return min <= host_addr && host_addr < max;
}
-EXPORT_SYMBOL(gasket_page_table_map);
/*
- * See gasket_page_table.h for general description.
- *
- * gasket_page_table_unmap takes the page table lock and calls either
- * gasket_unmap_simple_pages() or gasket_unmap_extended_pages() to
- * actually unmap the pages from device space.
+ * Get and map last level page table buffers.
*
- * The page table mutex is held for the entire operation.
+ * slots is the location(s) to write device-mapped page address. If this is a
+ * simple mapping, these will be address translation registers. If this is
+ * an extended mapping, these will be within a second-level page table
+ * allocated by the host and so must have their __iomem attribute casted away.
*/
-void gasket_page_table_unmap(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+static int gasket_perform_mapping(
+ struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *ptes,
+ u64 __iomem *slots, ulong host_addr, uint num_pages,
+ int is_simple_mapping)
{
- if (!num_pages)
- return;
+ int ret;
+ ulong offset;
+ struct page *page;
+ dma_addr_t dma_addr;
+ ulong page_addr;
+ int i;
- mutex_lock(&pg_tbl->mutex);
- gasket_page_table_unmap_nolock(pg_tbl, dev_addr, num_pages);
- mutex_unlock(&pg_tbl->mutex);
-}
-EXPORT_SYMBOL(gasket_page_table_unmap);
+ for (i = 0; i < num_pages; i++) {
+ page_addr = host_addr + i * PAGE_SIZE;
+ offset = page_addr & (PAGE_SIZE - 1);
+ dev_dbg(pg_tbl->device, "%s i %d\n", __func__, i);
+ if (is_coherent(pg_tbl, host_addr)) {
+ u64 off =
+ (u64)host_addr -
+ (u64)pg_tbl->coherent_pages[0].user_virt;
+ ptes[i].page = NULL;
+ ptes[i].offset = offset;
+ ptes[i].dma_addr = pg_tbl->coherent_pages[0].paddr +
+ off + i * PAGE_SIZE;
+ } else {
+ ret = get_user_pages_fast(
+ page_addr - offset, 1, 1, &page);
-static void gasket_page_table_unmap_all_nolock(struct gasket_page_table *pg_tbl)
-{
- gasket_unmap_simple_pages(
- pg_tbl, gasket_components_to_dev_address(pg_tbl, 1, 0, 0),
- pg_tbl->num_simple_entries);
- gasket_unmap_extended_pages(
- pg_tbl, gasket_components_to_dev_address(pg_tbl, 0, 0, 0),
- pg_tbl->num_extended_entries * GASKET_PAGES_PER_SUBTABLE);
-}
+ if (ret <= 0) {
+ dev_err(pg_tbl->device,
+ "get user pages failed for addr=0x%lx, "
+ "offset=0x%lx [ret=%d]\n",
+ page_addr, offset, ret);
+ return ret ? ret : -ENOMEM;
+ }
+ ++pg_tbl->num_active_pages;
-/* See gasket_page_table.h for description. */
-void gasket_page_table_unmap_all(struct gasket_page_table *pg_tbl)
-{
- mutex_lock(&pg_tbl->mutex);
- gasket_page_table_unmap_all_nolock(pg_tbl);
- mutex_unlock(&pg_tbl->mutex);
-}
-EXPORT_SYMBOL(gasket_page_table_unmap_all);
+ ptes[i].page = page;
+ ptes[i].offset = offset;
-/* See gasket_page_table.h for description. */
-void gasket_page_table_reset(struct gasket_page_table *pg_tbl)
-{
- mutex_lock(&pg_tbl->mutex);
- gasket_page_table_unmap_all_nolock(pg_tbl);
- writeq(pg_tbl->config.total_entries, pg_tbl->extended_offset_reg);
- mutex_unlock(&pg_tbl->mutex);
-}
+ /* Map the page into DMA space. */
+ ptes[i].dma_addr =
+ dma_map_page(pg_tbl->device, page, 0, PAGE_SIZE,
+ DMA_BIDIRECTIONAL);
+ dev_dbg(pg_tbl->device,
+ "%s i %d pte %p pfn %p -> mapped %llx\n",
+ __func__, i, &ptes[i],
+ (void *)page_to_pfn(page),
+ (unsigned long long)ptes[i].dma_addr);
-/* See gasket_page_table.h for description. */
-void gasket_page_table_garbage_collect(struct gasket_page_table *pg_tbl)
-{
- mutex_lock(&pg_tbl->mutex);
- gasket_page_table_garbage_collect_nolock(pg_tbl);
- mutex_unlock(&pg_tbl->mutex);
-}
+ if (ptes[i].dma_addr == -1) {
+ dev_dbg(pg_tbl->device,
+ "%s i %d -> fail to map page %llx "
+ "[pfn %p ohys %p]\n",
+ __func__, i,
+ (unsigned long long)ptes[i].dma_addr,
+ (void *)page_to_pfn(page),
+ (void *)page_to_phys(page));
+ return -1;
+ }
+ /* Wait until the page is mapped. */
+ mb();
+ }
-/* See gasket_page_table.h for description. */
-int gasket_page_table_lookup_page(
- struct gasket_page_table *pg_tbl, ulong dev_addr, struct page **ppage,
- ulong *poffset)
-{
- uint page_num;
- struct gasket_page_table_entry *pte;
-
- mutex_lock(&pg_tbl->mutex);
- if (gasket_addr_is_simple(pg_tbl, dev_addr)) {
- page_num = gasket_simple_page_idx(pg_tbl, dev_addr);
- if (page_num >= pg_tbl->num_simple_entries)
- goto fail;
-
- pte = pg_tbl->entries + page_num;
- if (pte->status != PTE_INUSE)
- goto fail;
- } else {
- /* Find the level 0 entry, */
- page_num = gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
- if (page_num >= pg_tbl->num_extended_entries)
- goto fail;
-
- pte = pg_tbl->entries + pg_tbl->num_simple_entries + page_num;
- if (pte->status != PTE_INUSE)
- goto fail;
+ /* Make the DMA-space address available to the device. */
+ dma_addr = (ptes[i].dma_addr + offset) | GASKET_VALID_SLOT_FLAG;
- /* and its contained level 1 entry. */
- page_num = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
- pte = pte->sublevel + page_num;
- if (pte->status != PTE_INUSE)
- goto fail;
+ if (is_simple_mapping) {
+ writeq(dma_addr, &slots[i]);
+ } else {
+ ((u64 __force *)slots)[i] = dma_addr;
+ /* Extended page table vectors are in DRAM,
+ * and so need to be synced each time they are updated.
+ */
+ dma_map_single(pg_tbl->device,
+ (void *)&((u64 __force *)slots)[i],
+ sizeof(u64), DMA_TO_DEVICE);
+ }
+ ptes[i].status = PTE_INUSE;
}
-
- *ppage = pte->page;
- *poffset = pte->offset;
- mutex_unlock(&pg_tbl->mutex);
return 0;
-
-fail:
- *ppage = NULL;
- *poffset = 0;
- mutex_unlock(&pg_tbl->mutex);
- return -1;
-}
-
-/* See gasket_page_table.h for description. */
-bool gasket_page_table_are_addrs_bad(
- struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr,
- ulong bytes)
-{
- if (host_addr & (PAGE_SIZE - 1)) {
- dev_err(pg_tbl->device,
- "host mapping address 0x%lx must be page aligned\n",
- host_addr);
- return true;
- }
-
- return gasket_page_table_is_dev_addr_bad(pg_tbl, dev_addr, bytes);
}
-EXPORT_SYMBOL(gasket_page_table_are_addrs_bad);
-/* See gasket_page_table.h for description. */
-bool gasket_page_table_is_dev_addr_bad(
- struct gasket_page_table *pg_tbl, ulong dev_addr, ulong bytes)
+/*
+ * Return the index of the page for the address in the simple table.
+ * Does not perform validity checking.
+ */
+static int gasket_simple_page_idx(
+ struct gasket_page_table *pg_tbl, ulong dev_addr)
{
- uint num_pages = bytes / PAGE_SIZE;
-
- if (bytes & (PAGE_SIZE - 1)) {
- dev_err(pg_tbl->device,
- "mapping size 0x%lX must be page aligned\n", bytes);
- return true;
- }
-
- if (num_pages == 0) {
- dev_err(pg_tbl->device,
- "requested mapping is less than one page: %lu / %lu\n",
- bytes, PAGE_SIZE);
- return true;
- }
-
- if (gasket_addr_is_simple(pg_tbl, dev_addr))
- return gasket_is_simple_dev_addr_bad(
- pg_tbl, dev_addr, num_pages);
- return gasket_is_extended_dev_addr_bad(pg_tbl, dev_addr, num_pages);
+ return (dev_addr >> GASKET_SIMPLE_PAGE_SHIFT) &
+ (pg_tbl->config.total_entries - 1);
}
-EXPORT_SYMBOL(gasket_page_table_is_dev_addr_bad);
-/* See gasket_page_table.h for description. */
-uint gasket_page_table_max_size(struct gasket_page_table *page_table)
+/*
+ * Return the level 0 page index for the given address.
+ * Does not perform validity checking.
+ */
+static ulong gasket_extended_lvl0_page_idx(
+ struct gasket_page_table *pg_tbl, ulong dev_addr)
{
- if (!page_table)
- return 0;
- return page_table->config.total_entries;
+ return (dev_addr >> GASKET_EXTENDED_LVL0_SHIFT) &
+ ((1 << GASKET_EXTENDED_LVL0_WIDTH) - 1);
}
-EXPORT_SYMBOL(gasket_page_table_max_size);
-/* See gasket_page_table.h for description. */
-uint gasket_page_table_num_entries(struct gasket_page_table *pg_tbl)
+/*
+ * Return the level 1 page index for the given address.
+ * Does not perform validity checking.
+ */
+static ulong gasket_extended_lvl1_page_idx(
+ struct gasket_page_table *pg_tbl, ulong dev_addr)
{
- if (!pg_tbl)
- return 0;
- return pg_tbl->num_simple_entries + pg_tbl->num_extended_entries;
+ return (dev_addr >> GASKET_EXTENDED_LVL1_SHIFT) &
+ (GASKET_PAGES_PER_SUBTABLE - 1);
}
-EXPORT_SYMBOL(gasket_page_table_num_entries);
-/* See gasket_page_table.h for description. */
-uint gasket_page_table_num_simple_entries(struct gasket_page_table *pg_tbl)
+/*
+ * Allocate page table entries in a simple table.
+ * The page table mutex must be held by the caller.
+ */
+static int gasket_alloc_simple_entries(
+ struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
{
- if (!pg_tbl)
- return 0;
- return pg_tbl->num_simple_entries;
-}
-EXPORT_SYMBOL(gasket_page_table_num_simple_entries);
+ if (!gasket_is_pte_range_free(
+ pg_tbl->entries + gasket_simple_page_idx(pg_tbl, dev_addr),
+ num_pages))
+ return -EBUSY;
-/* See gasket_page_table.h for description. */
-uint gasket_page_table_num_active_pages(struct gasket_page_table *pg_tbl)
-{
- if (!pg_tbl)
- return 0;
- return pg_tbl->num_active_pages;
+ return 0;
}
-EXPORT_SYMBOL(gasket_page_table_num_active_pages);
-/* See gasket_page_table.h */
-int gasket_page_table_system_status(struct gasket_page_table *page_table)
+/* Safely return a page to the OS. */
+static bool gasket_release_page(struct page *page)
{
- if (!page_table)
- return GASKET_STATUS_LAMED;
+ if (!page)
+ return false;
- if (gasket_page_table_num_entries(page_table) == 0) {
- dev_dbg(page_table->device, "Page table size is 0\n");
- return GASKET_STATUS_LAMED;
- }
+ if (!PageReserved(page))
+ SetPageDirty(page);
+ put_page(page);
- return GASKET_STATUS_ALIVE;
+ return true;
}
/*
- * Allocate and map pages to simple addresses.
- * If there is an error, no pages are mapped.
+ * Unmap and release mapped pages.
+ * The page table mutex must be held by the caller.
*/
-static int gasket_map_simple_pages(
- struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr,
- uint num_pages)
+static void gasket_perform_unmapping(
+ struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *ptes,
+ u64 __iomem *slots, uint num_pages, int is_simple_mapping)
{
- int ret;
- uint slot_idx = gasket_simple_page_idx(pg_tbl, dev_addr);
+ int i;
+ /*
+ * For each page table entry and corresponding entry in the device's
+ * address translation table:
+ */
+ for (i = 0; i < num_pages; i++) {
+ /* release the address from the device, */
+ if (is_simple_mapping || ptes[i].status == PTE_INUSE)
+ writeq(0, &slots[i]);
+ else
+ ((u64 __force *)slots)[i] = 0;
+ /* Force sync around the address release. */
+ mb();
- ret = gasket_alloc_simple_entries(pg_tbl, dev_addr, num_pages);
- if (ret) {
- dev_err(pg_tbl->device,
- "page table slots %u (@ 0x%lx) to %u are not available\n",
- slot_idx, dev_addr, slot_idx + num_pages - 1);
- return ret;
+ /* release the address from the driver, */
+ if (ptes[i].status == PTE_INUSE) {
+ if (ptes[i].dma_addr) {
+ dma_unmap_page(pg_tbl->device, ptes[i].dma_addr,
+ PAGE_SIZE, DMA_FROM_DEVICE);
+ }
+ if (gasket_release_page(ptes[i].page))
+ --pg_tbl->num_active_pages;
+ }
+ ptes[i].status = PTE_FREE;
+
+ /* and clear the PTE. */
+ memset(&ptes[i], 0, sizeof(struct gasket_page_table_entry));
}
+}
- ret = gasket_perform_mapping(
- pg_tbl, pg_tbl->entries + slot_idx,
- pg_tbl->base_slot + slot_idx, host_addr, num_pages, 1);
+/*
+ * Unmap and release pages mapped to simple addresses.
+ * The page table mutex must be held by the caller.
+ */
+static void gasket_unmap_simple_pages(
+ struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+{
+ uint slot = gasket_simple_page_idx(pg_tbl, dev_addr);
- if (ret) {
- gasket_page_table_unmap_nolock(pg_tbl, dev_addr, num_pages);
- dev_err(pg_tbl->device, "gasket_perform_mapping %d\n", ret);
- }
- return ret;
+ gasket_perform_unmapping(pg_tbl, pg_tbl->entries + slot,
+ pg_tbl->base_slot + slot, num_pages, 1);
}
/*
- * gasket_map_extended_pages - Get and map buffers to extended addresses.
- * If there is an error, no pages are mapped.
+ * Unmap and release buffers to extended addresses.
+ * The page table mutex must be held by the caller.
*/
-static int gasket_map_extended_pages(
- struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr,
- uint num_pages)
+static void gasket_unmap_extended_pages(
+ struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
{
- int ret;
- ulong dev_addr_end;
uint slot_idx, remain, len;
struct gasket_page_table_entry *pte;
u64 __iomem *slot_base;
- ret = gasket_alloc_extended_entries(pg_tbl, dev_addr, num_pages);
- if (ret) {
- dev_addr_end = dev_addr + (num_pages / PAGE_SIZE) - 1;
- dev_err(pg_tbl->device,
- "page table slots (%lu,%lu) (@ 0x%lx) to (%lu,%lu) are "
- "not available\n",
- gasket_extended_lvl0_page_idx(pg_tbl, dev_addr),
- dev_addr,
- gasket_extended_lvl1_page_idx(pg_tbl, dev_addr),
- gasket_extended_lvl0_page_idx(pg_tbl, dev_addr_end),
- gasket_extended_lvl1_page_idx(pg_tbl, dev_addr_end));
- return ret;
- }
-
remain = num_pages;
slot_idx = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
pte = pg_tbl->entries + pg_tbl->num_simple_entries +
gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
while (remain > 0) {
+ /* TODO: Add check to ensure pte remains valid? */
len = min(remain, GASKET_PAGES_PER_SUBTABLE - slot_idx);
- slot_base =
- (u64 __iomem *)(page_address(pte->page) + pte->offset);
- ret = gasket_perform_mapping(
- pg_tbl, pte->sublevel + slot_idx, slot_base + slot_idx,
- host_addr, len, 0);
- if (ret) {
- gasket_page_table_unmap_nolock(
- pg_tbl, dev_addr, num_pages);
- return ret;
+ if (pte->status == PTE_INUSE) {
+ slot_base = (u64 __iomem *)(page_address(pte->page) +
+ pte->offset);
+ gasket_perform_unmapping(
+ pg_tbl, pte->sublevel + slot_idx,
+ slot_base + slot_idx, len, 0);
}
remain -= len;
slot_idx = 0;
pte++;
- host_addr += len * PAGE_SIZE;
}
-
- return 0;
}
-/*
- * Get and map last level page table buffers.
- *
- * slots is the location(s) to write device-mapped page address. If this is a
- * simple mapping, these will be address translation registers. If this is
- * an extended mapping, these will be within a second-level page table
- * allocated by the host and so must have their __iomem attribute casted away.
- */
-static int gasket_perform_mapping(
- struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *ptes,
- u64 __iomem *slots, ulong host_addr, uint num_pages,
- int is_simple_mapping)
+/* Evaluates to nonzero if the specified virtual address is simple. */
+static inline bool gasket_addr_is_simple(
+ struct gasket_page_table *pg_tbl, ulong addr)
{
- int ret;
- ulong offset;
- struct page *page;
- dma_addr_t dma_addr;
- ulong page_addr;
- int i;
-
- for (i = 0; i < num_pages; i++) {
- page_addr = host_addr + i * PAGE_SIZE;
- offset = page_addr & (PAGE_SIZE - 1);
- dev_dbg(pg_tbl->device, "%s i %d\n", __func__, i);
- if (is_coherent(pg_tbl, host_addr)) {
- u64 off =
- (u64)host_addr -
- (u64)pg_tbl->coherent_pages[0].user_virt;
- ptes[i].page = NULL;
- ptes[i].offset = offset;
- ptes[i].dma_addr = pg_tbl->coherent_pages[0].paddr +
- off + i * PAGE_SIZE;
- } else {
- ret = get_user_pages_fast(
- page_addr - offset, 1, 1, &page);
-
- if (ret <= 0) {
- dev_err(pg_tbl->device,
- "get user pages failed for addr=0x%lx, "
- "offset=0x%lx [ret=%d]\n",
- page_addr, offset, ret);
- return ret ? ret : -ENOMEM;
- }
- ++pg_tbl->num_active_pages;
-
- ptes[i].page = page;
- ptes[i].offset = offset;
-
- /* Map the page into DMA space. */
- ptes[i].dma_addr =
- dma_map_page(pg_tbl->device, page, 0, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
- dev_dbg(pg_tbl->device,
- "%s i %d pte %p pfn %p -> mapped %llx\n",
- __func__, i, &ptes[i],
- (void *)page_to_pfn(page),
- (unsigned long long)ptes[i].dma_addr);
-
- if (ptes[i].dma_addr == -1) {
- dev_dbg(pg_tbl->device,
- "%s i %d -> fail to map page %llx "
- "[pfn %p ohys %p]\n",
- __func__, i,
- (unsigned long long)ptes[i].dma_addr,
- (void *)page_to_pfn(page),
- (void *)page_to_phys(page));
- return -1;
- }
- /* Wait until the page is mapped. */
- mb();
- }
-
- /* Make the DMA-space address available to the device. */
- dma_addr = (ptes[i].dma_addr + offset) | GASKET_VALID_SLOT_FLAG;
-
- if (is_simple_mapping) {
- writeq(dma_addr, &slots[i]);
- } else {
- ((u64 __force *)slots)[i] = dma_addr;
- /* Extended page table vectors are in DRAM,
- * and so need to be synced each time they are updated.
- */
- dma_map_single(pg_tbl->device,
- (void *)&((u64 __force *)slots)[i],
- sizeof(u64), DMA_TO_DEVICE);
- }
- ptes[i].status = PTE_INUSE;
- }
- return 0;
+ return !((addr) & (pg_tbl)->extended_flag);
}
/*
- * Allocate page table entries in a simple table.
- * The page table mutex must be held by the caller.
+ * Convert (simple, page, offset) into a device address.
+ * Examples:
+ * Simple page 0, offset 32:
+ * Input (0, 0, 32), Output 0x20
+ * Simple page 1000, offset 511:
+ * Input (0, 1000, 512), Output 0x3E81FF
+ * Extended page 0, offset 32:
+ * Input (0, 0, 32), Output 0x8000000020
+ * Extended page 1000, offset 511:
+ * Input (1, 1000, 512), Output 0x8003E81FF
*/
-static int gasket_alloc_simple_entries(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+static ulong gasket_components_to_dev_address(
+ struct gasket_page_table *pg_tbl, int is_simple, uint page_index,
+ uint offset)
{
- if (!gasket_is_pte_range_free(
- pg_tbl->entries + gasket_simple_page_idx(pg_tbl, dev_addr),
- num_pages))
- return -EBUSY;
+ ulong lvl0_index, lvl1_index;
- return 0;
+ if (is_simple) {
+ /* Return simple addresses directly. */
+ lvl0_index = page_index & (pg_tbl->config.total_entries - 1);
+ return (lvl0_index << GASKET_SIMPLE_PAGE_SHIFT) | offset;
+ }
+
+ /*
+ * This could be compressed into fewer statements, but
+ * A) the compiler should optimize it
+ * B) this is not slow
+ * C) this is an uncommon operation
+ * D) this is actually readable this way.
+ */
+ lvl0_index = page_index / GASKET_PAGES_PER_SUBTABLE;
+ lvl1_index = page_index & (GASKET_PAGES_PER_SUBTABLE - 1);
+ return (pg_tbl)->extended_flag |
+ (lvl0_index << GASKET_EXTENDED_LVL0_SHIFT) |
+ (lvl1_index << GASKET_EXTENDED_LVL1_SHIFT) | offset;
}
/*
- * Allocate slots in an extended page table. Check to see if a range of page
- * table slots are available. If necessary, memory is allocated for second level
- * page tables.
- *
- * Note that memory for second level page tables is allocated as needed, but
- * that memory is only freed on the final close of the device file, when the
- * page tables are repartitioned, or the the device is removed. If there is an
- * error or if the full range of slots is not available, any memory
- * allocated for second level page tables remains allocated until final close,
- * repartition, or device removal.
+ * Validity checking for simple addresses.
*
- * The page table mutex must be held by the caller.
+ * Verify that address translation commutes (from address to/from page + offset)
+ * and that the requested page range starts and ends within the set of
+ * currently-partitioned simple pages.
*/
-static int gasket_alloc_extended_entries(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_entries)
+static bool gasket_is_simple_dev_addr_bad(
+ struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
{
- int ret = 0;
- uint remain, subtable_slot_idx, len;
- struct gasket_page_table_entry *pte;
- u64 __iomem *slot;
-
- remain = num_entries;
- subtable_slot_idx = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
- pte = pg_tbl->entries + pg_tbl->num_simple_entries +
- gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
- slot = pg_tbl->base_slot + pg_tbl->num_simple_entries +
- gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
+ ulong page_offset = dev_addr & (PAGE_SIZE - 1);
+ ulong page_index =
+ (dev_addr / PAGE_SIZE) & (pg_tbl->config.total_entries - 1);
- while (remain > 0) {
- len = min(remain,
- GASKET_PAGES_PER_SUBTABLE - subtable_slot_idx);
+ if (gasket_components_to_dev_address(
+ pg_tbl, 1, page_index, page_offset) != dev_addr) {
+ dev_err(pg_tbl->device, "address is invalid, 0x%lX\n",
+ dev_addr);
+ return true;
+ }
- if (pte->status == PTE_FREE) {
- ret = gasket_alloc_extended_subtable(pg_tbl, pte, slot);
- if (ret) {
- dev_err(pg_tbl->device,
- "no memory for extended addr subtable\n");
- return ret;
- }
- } else {
- if (!gasket_is_pte_range_free(
- pte->sublevel + subtable_slot_idx, len))
- return -EBUSY;
- }
+ if (page_index >= pg_tbl->num_simple_entries) {
+ dev_err(pg_tbl->device,
+ "starting slot at %lu is too large, max is < %u\n",
+ page_index, pg_tbl->num_simple_entries);
+ return true;
+ }
- remain -= len;
- subtable_slot_idx = 0;
- pte++;
- slot++;
+ if (page_index + num_pages > pg_tbl->num_simple_entries) {
+ dev_err(pg_tbl->device,
+ "ending slot at %lu is too large, max is <= %u\n",
+ page_index + num_pages, pg_tbl->num_simple_entries);
+ return true;
}
- return 0;
+ return false;
}
/*
- * Allocate a second level page table.
- * The page table mutex must be held by the caller.
+ * Validity checking for extended addresses.
+ *
+ * Verify that address translation commutes (from address to/from page +
+ * offset) and that the requested page range starts and ends within the set of
+ * currently-partitioned extended pages.
*/
-static int gasket_alloc_extended_subtable(
- struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *pte,
- u64 __iomem *slot)
+static bool gasket_is_extended_dev_addr_bad(
+ struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
{
- ulong page_addr, subtable_bytes;
- dma_addr_t dma_addr;
+ /* Starting byte index of dev_addr into the first mapped page */
+ ulong page_offset = dev_addr & (PAGE_SIZE - 1);
+ ulong page_global_idx, page_lvl0_idx;
+ ulong num_lvl0_pages;
+ ulong addr;
- /* XXX FIX ME XXX this is inefficient for non-4K page sizes */
+ /* check if the device address is out of bound */
+ addr = dev_addr & ~((pg_tbl)->extended_flag);
+ if (addr >> (GASKET_EXTENDED_LVL0_WIDTH + GASKET_EXTENDED_LVL0_SHIFT)) {
+ dev_err(pg_tbl->device, "device address out of bounds: 0x%lx\n",
+ dev_addr);
+ return true;
+ }
- /* GFP_DMA flag must be passed to architectures for which
- * part of the memory range is not considered DMA'able.
- * This seems to be the case for Juno board with 4.5.0 Linaro kernel
+ /* Find the starting sub-page index in the space of all sub-pages. */
+ page_global_idx = (dev_addr / PAGE_SIZE) &
+ (pg_tbl->config.total_entries * GASKET_PAGES_PER_SUBTABLE - 1);
+
+ /* Find the starting level 0 index. */
+ page_lvl0_idx = gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
+
+ /* Get the count of affected level 0 pages. */
+ num_lvl0_pages = (num_pages + GASKET_PAGES_PER_SUBTABLE - 1) /
+ GASKET_PAGES_PER_SUBTABLE;
+
+ if (gasket_components_to_dev_address(
+ pg_tbl, 0, page_global_idx, page_offset) != dev_addr) {
+ dev_err(pg_tbl->device, "address is invalid: 0x%lx\n",
+ dev_addr);
+ return true;
+ }
+
+ if (page_lvl0_idx >= pg_tbl->num_extended_entries) {
+ dev_err(pg_tbl->device,
+ "starting level 0 slot at %lu is too large, max is < "
+ "%u\n", page_lvl0_idx, pg_tbl->num_extended_entries);
+ return true;
+ }
+
+ if (page_lvl0_idx + num_lvl0_pages > pg_tbl->num_extended_entries) {
+ dev_err(pg_tbl->device,
+ "ending level 0 slot at %lu is too large, max is <= %u\n",
+ page_lvl0_idx + num_lvl0_pages,
+ pg_tbl->num_extended_entries);
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * Non-locking entry to unmapping routines.
+ * The page table mutex must be held by the caller.
+ */
+static void gasket_page_table_unmap_nolock(
+ struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+{
+ if (!num_pages)
+ return;
+
+ if (gasket_addr_is_simple(pg_tbl, dev_addr))
+ gasket_unmap_simple_pages(pg_tbl, dev_addr, num_pages);
+ else
+ gasket_unmap_extended_pages(pg_tbl, dev_addr, num_pages);
+}
+
+/*
+ * Allocate and map pages to simple addresses.
+ * If there is an error, no pages are mapped.
+ */
+static int gasket_map_simple_pages(
+ struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr,
+ uint num_pages)
+{
+ int ret;
+ uint slot_idx = gasket_simple_page_idx(pg_tbl, dev_addr);
+
+ ret = gasket_alloc_simple_entries(pg_tbl, dev_addr, num_pages);
+ if (ret) {
+ dev_err(pg_tbl->device,
+ "page table slots %u (@ 0x%lx) to %u are not available\n",
+ slot_idx, dev_addr, slot_idx + num_pages - 1);
+ return ret;
+ }
+
+ ret = gasket_perform_mapping(
+ pg_tbl, pg_tbl->entries + slot_idx,
+ pg_tbl->base_slot + slot_idx, host_addr, num_pages, 1);
+
+ if (ret) {
+ gasket_page_table_unmap_nolock(pg_tbl, dev_addr, num_pages);
+ dev_err(pg_tbl->device, "gasket_perform_mapping %d\n", ret);
+ }
+ return ret;
+}
+
+/*
+ * Allocate a second level page table.
+ * The page table mutex must be held by the caller.
+ */
+static int gasket_alloc_extended_subtable(
+ struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *pte,
+ u64 __iomem *slot)
+{
+ ulong page_addr, subtable_bytes;
+ dma_addr_t dma_addr;
+
+ /* XXX FIX ME XXX this is inefficient for non-4K page sizes */
+
+ /* GFP_DMA flag must be passed to architectures for which
+ * part of the memory range is not considered DMA'able.
+ * This seems to be the case for Juno board with 4.5.0 Linaro kernel
*/
page_addr = get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!page_addr)
@@ -930,384 +911,338 @@ static int gasket_alloc_extended_subtable(
}
/*
- * Non-locking entry to unmapping routines.
+ * Allocate slots in an extended page table. Check to see if a range of page
+ * table slots are available. If necessary, memory is allocated for second level
+ * page tables.
+ *
+ * Note that memory for second level page tables is allocated as needed, but
+ * that memory is only freed on the final close of the device file, when the
+ * page tables are repartitioned, or the the device is removed. If there is an
+ * error or if the full range of slots is not available, any memory
+ * allocated for second level page tables remains allocated until final close,
+ * repartition, or device removal.
+ *
* The page table mutex must be held by the caller.
*/
-static void gasket_page_table_unmap_nolock(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+static int gasket_alloc_extended_entries(
+ struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_entries)
{
- if (!num_pages)
- return;
+ int ret = 0;
+ uint remain, subtable_slot_idx, len;
+ struct gasket_page_table_entry *pte;
+ u64 __iomem *slot;
- if (gasket_addr_is_simple(pg_tbl, dev_addr))
- gasket_unmap_simple_pages(pg_tbl, dev_addr, num_pages);
- else
- gasket_unmap_extended_pages(pg_tbl, dev_addr, num_pages);
-}
+ remain = num_entries;
+ subtable_slot_idx = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
+ pte = pg_tbl->entries + pg_tbl->num_simple_entries +
+ gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
+ slot = pg_tbl->base_slot + pg_tbl->num_simple_entries +
+ gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
-/*
- * Unmap and release pages mapped to simple addresses.
- * The page table mutex must be held by the caller.
- */
-static void gasket_unmap_simple_pages(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
-{
- uint slot = gasket_simple_page_idx(pg_tbl, dev_addr);
+ while (remain > 0) {
+ len = min(remain,
+ GASKET_PAGES_PER_SUBTABLE - subtable_slot_idx);
- gasket_perform_unmapping(pg_tbl, pg_tbl->entries + slot,
- pg_tbl->base_slot + slot, num_pages, 1);
+ if (pte->status == PTE_FREE) {
+ ret = gasket_alloc_extended_subtable(pg_tbl, pte, slot);
+ if (ret) {
+ dev_err(pg_tbl->device,
+ "no memory for extended addr subtable\n");
+ return ret;
+ }
+ } else {
+ if (!gasket_is_pte_range_free(
+ pte->sublevel + subtable_slot_idx, len))
+ return -EBUSY;
+ }
+
+ remain -= len;
+ subtable_slot_idx = 0;
+ pte++;
+ slot++;
+ }
+
+ return 0;
}
/*
- * Unmap and release buffers to extended addresses.
- * The page table mutex must be held by the caller.
+ * gasket_map_extended_pages - Get and map buffers to extended addresses.
+ * If there is an error, no pages are mapped.
*/
-static void gasket_unmap_extended_pages(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+static int gasket_map_extended_pages(
+ struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr,
+ uint num_pages)
{
+ int ret;
+ ulong dev_addr_end;
uint slot_idx, remain, len;
struct gasket_page_table_entry *pte;
u64 __iomem *slot_base;
+ ret = gasket_alloc_extended_entries(pg_tbl, dev_addr, num_pages);
+ if (ret) {
+ dev_addr_end = dev_addr + (num_pages / PAGE_SIZE) - 1;
+ dev_err(pg_tbl->device,
+ "page table slots (%lu,%lu) (@ 0x%lx) to (%lu,%lu) are "
+ "not available\n",
+ gasket_extended_lvl0_page_idx(pg_tbl, dev_addr),
+ dev_addr,
+ gasket_extended_lvl1_page_idx(pg_tbl, dev_addr),
+ gasket_extended_lvl0_page_idx(pg_tbl, dev_addr_end),
+ gasket_extended_lvl1_page_idx(pg_tbl, dev_addr_end));
+ return ret;
+ }
+
remain = num_pages;
slot_idx = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
pte = pg_tbl->entries + pg_tbl->num_simple_entries +
gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
while (remain > 0) {
- /* TODO: Add check to ensure pte remains valid? */
len = min(remain, GASKET_PAGES_PER_SUBTABLE - slot_idx);
- if (pte->status == PTE_INUSE) {
- slot_base = (u64 __iomem *)(page_address(pte->page) +
- pte->offset);
- gasket_perform_unmapping(
- pg_tbl, pte->sublevel + slot_idx,
- slot_base + slot_idx, len, 0);
+ slot_base =
+ (u64 __iomem *)(page_address(pte->page) + pte->offset);
+ ret = gasket_perform_mapping(
+ pg_tbl, pte->sublevel + slot_idx, slot_base + slot_idx,
+ host_addr, len, 0);
+ if (ret) {
+ gasket_page_table_unmap_nolock(
+ pg_tbl, dev_addr, num_pages);
+ return ret;
}
remain -= len;
slot_idx = 0;
pte++;
+ host_addr += len * PAGE_SIZE;
}
+
+ return 0;
}
/*
- * Unmap and release mapped pages.
- * The page table mutex must be held by the caller.
+ * See gasket_page_table.h for general description.
+ *
+ * gasket_page_table_map calls either gasket_map_simple_pages() or
+ * gasket_map_extended_pages() to actually perform the mapping.
+ *
+ * The page table mutex is held for the entire operation.
*/
-static void gasket_perform_unmapping(
- struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *ptes,
- u64 __iomem *slots, uint num_pages, int is_simple_mapping)
+int gasket_page_table_map(
+ struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr,
+ uint num_pages)
{
- int i;
- /*
- * For each page table entry and corresponding entry in the device's
- * address translation table:
- */
- for (i = 0; i < num_pages; i++) {
- /* release the address from the device, */
- if (is_simple_mapping || ptes[i].status == PTE_INUSE)
- writeq(0, &slots[i]);
- else
- ((u64 __force *)slots)[i] = 0;
- /* Force sync around the address release. */
- mb();
+ int ret;
- /* release the address from the driver, */
- if (ptes[i].status == PTE_INUSE) {
- if (ptes[i].dma_addr) {
- dma_unmap_page(pg_tbl->device, ptes[i].dma_addr,
- PAGE_SIZE, DMA_FROM_DEVICE);
- }
- if (gasket_release_page(ptes[i].page))
- --pg_tbl->num_active_pages;
- }
- ptes[i].status = PTE_FREE;
+ if (!num_pages)
+ return 0;
- /* and clear the PTE. */
- memset(&ptes[i], 0, sizeof(struct gasket_page_table_entry));
- }
-}
+ mutex_lock(&pg_tbl->mutex);
-/*
- * Free a second level page [sub]table.
- * The page table mutex must be held before this call.
- */
-static void gasket_free_extended_subtable(
- struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *pte,
- u64 __iomem *slot)
-{
- /* Release the page table from the driver */
- pte->status = PTE_FREE;
-
- /* Release the page table from the device */
- writeq(0, slot);
- /* Force sync around the address release. */
- mb();
+ if (gasket_addr_is_simple(pg_tbl, dev_addr)) {
+ ret = gasket_map_simple_pages(
+ pg_tbl, host_addr, dev_addr, num_pages);
+ } else {
+ ret = gasket_map_extended_pages(
+ pg_tbl, host_addr, dev_addr, num_pages);
+ }
- if (pte->dma_addr)
- dma_unmap_page(pg_tbl->device, pte->dma_addr, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
+ mutex_unlock(&pg_tbl->mutex);
- vfree(pte->sublevel);
+ dev_dbg(pg_tbl->device,
+ "%s done: ha %llx daddr %llx num %d, ret %d\n",
+ __func__, (unsigned long long)host_addr,
+ (unsigned long long)dev_addr, num_pages, ret);
+ return ret;
+}
+EXPORT_SYMBOL(gasket_page_table_map);
- if (pte->page)
- free_page((ulong)page_address(pte->page));
+/*
+ * See gasket_page_table.h for general description.
+ *
+ * gasket_page_table_unmap takes the page table lock and calls either
+ * gasket_unmap_simple_pages() or gasket_unmap_extended_pages() to
+ * actually unmap the pages from device space.
+ *
+ * The page table mutex is held for the entire operation.
+ */
+void gasket_page_table_unmap(
+ struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+{
+ if (!num_pages)
+ return;
- memset(pte, 0, sizeof(struct gasket_page_table_entry));
+ mutex_lock(&pg_tbl->mutex);
+ gasket_page_table_unmap_nolock(pg_tbl, dev_addr, num_pages);
+ mutex_unlock(&pg_tbl->mutex);
}
+EXPORT_SYMBOL(gasket_page_table_unmap);
-/* Safely return a page to the OS. */
-static bool gasket_release_page(struct page *page)
+static void gasket_page_table_unmap_all_nolock(struct gasket_page_table *pg_tbl)
{
- if (!page)
- return false;
-
- if (!PageReserved(page))
- SetPageDirty(page);
- put_page(page);
+ gasket_unmap_simple_pages(
+ pg_tbl, gasket_components_to_dev_address(pg_tbl, 1, 0, 0),
+ pg_tbl->num_simple_entries);
+ gasket_unmap_extended_pages(
+ pg_tbl, gasket_components_to_dev_address(pg_tbl, 0, 0, 0),
+ pg_tbl->num_extended_entries * GASKET_PAGES_PER_SUBTABLE);
+}
- return true;
+/* See gasket_page_table.h for description. */
+void gasket_page_table_unmap_all(struct gasket_page_table *pg_tbl)
+{
+ mutex_lock(&pg_tbl->mutex);
+ gasket_page_table_unmap_all_nolock(pg_tbl);
+ mutex_unlock(&pg_tbl->mutex);
}
+EXPORT_SYMBOL(gasket_page_table_unmap_all);
-/* Evaluates to nonzero if the specified virtual address is simple. */
-static inline bool gasket_addr_is_simple(
- struct gasket_page_table *pg_tbl, ulong addr)
+/* See gasket_page_table.h for description. */
+void gasket_page_table_reset(struct gasket_page_table *pg_tbl)
{
- return !((addr) & (pg_tbl)->extended_flag);
+ mutex_lock(&pg_tbl->mutex);
+ gasket_page_table_unmap_all_nolock(pg_tbl);
+ writeq(pg_tbl->config.total_entries, pg_tbl->extended_offset_reg);
+ mutex_unlock(&pg_tbl->mutex);
}
-/*
- * Validity checking for simple addresses.
- *
- * Verify that address translation commutes (from address to/from page + offset)
- * and that the requested page range starts and ends within the set of
- * currently-partitioned simple pages.
- */
-static bool gasket_is_simple_dev_addr_bad(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+/* See gasket_page_table.h for description. */
+int gasket_page_table_lookup_page(
+ struct gasket_page_table *pg_tbl, ulong dev_addr, struct page **ppage,
+ ulong *poffset)
{
- ulong page_offset = dev_addr & (PAGE_SIZE - 1);
- ulong page_index =
- (dev_addr / PAGE_SIZE) & (pg_tbl->config.total_entries - 1);
+ uint page_num;
+ struct gasket_page_table_entry *pte;
- if (gasket_components_to_dev_address(
- pg_tbl, 1, page_index, page_offset) != dev_addr) {
- dev_err(pg_tbl->device, "address is invalid, 0x%lX\n",
- dev_addr);
- return true;
- }
+ mutex_lock(&pg_tbl->mutex);
+ if (gasket_addr_is_simple(pg_tbl, dev_addr)) {
+ page_num = gasket_simple_page_idx(pg_tbl, dev_addr);
+ if (page_num >= pg_tbl->num_simple_entries)
+ goto fail;
- if (page_index >= pg_tbl->num_simple_entries) {
- dev_err(pg_tbl->device,
- "starting slot at %lu is too large, max is < %u\n",
- page_index, pg_tbl->num_simple_entries);
- return true;
- }
+ pte = pg_tbl->entries + page_num;
+ if (pte->status != PTE_INUSE)
+ goto fail;
+ } else {
+ /* Find the level 0 entry, */
+ page_num = gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
+ if (page_num >= pg_tbl->num_extended_entries)
+ goto fail;
- if (page_index + num_pages > pg_tbl->num_simple_entries) {
- dev_err(pg_tbl->device,
- "ending slot at %lu is too large, max is <= %u\n",
- page_index + num_pages, pg_tbl->num_simple_entries);
- return true;
+ pte = pg_tbl->entries + pg_tbl->num_simple_entries + page_num;
+ if (pte->status != PTE_INUSE)
+ goto fail;
+
+ /* and its contained level 1 entry. */
+ page_num = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
+ pte = pte->sublevel + page_num;
+ if (pte->status != PTE_INUSE)
+ goto fail;
}
- return false;
+ *ppage = pte->page;
+ *poffset = pte->offset;
+ mutex_unlock(&pg_tbl->mutex);
+ return 0;
+
+fail:
+ *ppage = NULL;
+ *poffset = 0;
+ mutex_unlock(&pg_tbl->mutex);
+ return -1;
}
-/*
- * Validity checking for extended addresses.
- *
- * Verify that address translation commutes (from address to/from page +
- * offset) and that the requested page range starts and ends within the set of
- * currently-partitioned extended pages.
- */
-static bool gasket_is_extended_dev_addr_bad(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+/* See gasket_page_table.h for description. */
+bool gasket_page_table_are_addrs_bad(
+ struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr,
+ ulong bytes)
{
- /* Starting byte index of dev_addr into the first mapped page */
- ulong page_offset = dev_addr & (PAGE_SIZE - 1);
- ulong page_global_idx, page_lvl0_idx;
- ulong num_lvl0_pages;
- ulong addr;
-
- /* check if the device address is out of bound */
- addr = dev_addr & ~((pg_tbl)->extended_flag);
- if (addr >> (GASKET_EXTENDED_LVL0_WIDTH + GASKET_EXTENDED_LVL0_SHIFT)) {
- dev_err(pg_tbl->device, "device address out of bounds: 0x%lx\n",
- dev_addr);
+ if (host_addr & (PAGE_SIZE - 1)) {
+ dev_err(pg_tbl->device,
+ "host mapping address 0x%lx must be page aligned\n",
+ host_addr);
return true;
}
- /* Find the starting sub-page index in the space of all sub-pages. */
- page_global_idx = (dev_addr / PAGE_SIZE) &
- (pg_tbl->config.total_entries * GASKET_PAGES_PER_SUBTABLE - 1);
-
- /* Find the starting level 0 index. */
- page_lvl0_idx = gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
-
- /* Get the count of affected level 0 pages. */
- num_lvl0_pages = (num_pages + GASKET_PAGES_PER_SUBTABLE - 1) /
- GASKET_PAGES_PER_SUBTABLE;
+ return gasket_page_table_is_dev_addr_bad(pg_tbl, dev_addr, bytes);
+}
+EXPORT_SYMBOL(gasket_page_table_are_addrs_bad);
- if (gasket_components_to_dev_address(
- pg_tbl, 0, page_global_idx, page_offset) != dev_addr) {
- dev_err(pg_tbl->device, "address is invalid: 0x%lx\n",
- dev_addr);
- return true;
- }
+/* See gasket_page_table.h for description. */
+bool gasket_page_table_is_dev_addr_bad(
+ struct gasket_page_table *pg_tbl, ulong dev_addr, ulong bytes)
+{
+ uint num_pages = bytes / PAGE_SIZE;
- if (page_lvl0_idx >= pg_tbl->num_extended_entries) {
+ if (bytes & (PAGE_SIZE - 1)) {
dev_err(pg_tbl->device,
- "starting level 0 slot at %lu is too large, max is < "
- "%u\n", page_lvl0_idx, pg_tbl->num_extended_entries);
+ "mapping size 0x%lX must be page aligned\n", bytes);
return true;
}
- if (page_lvl0_idx + num_lvl0_pages > pg_tbl->num_extended_entries) {
+ if (num_pages == 0) {
dev_err(pg_tbl->device,
- "ending level 0 slot at %lu is too large, max is <= %u\n",
- page_lvl0_idx + num_lvl0_pages,
- pg_tbl->num_extended_entries);
+ "requested mapping is less than one page: %lu / %lu\n",
+ bytes, PAGE_SIZE);
return true;
}
- return false;
-}
-
-/*
- * Check if a range of PTEs is free.
- * The page table mutex must be held by the caller.
- */
-static bool gasket_is_pte_range_free(
- struct gasket_page_table_entry *ptes, uint num_entries)
-{
- int i;
-
- for (i = 0; i < num_entries; i++) {
- if (ptes[i].status != PTE_FREE)
- return false;
- }
-
- return true;
-}
-
-/*
- * Actually perform collection.
- * The page table mutex must be held by the caller.
- */
-static void gasket_page_table_garbage_collect_nolock(
- struct gasket_page_table *pg_tbl)
-{
- struct gasket_page_table_entry *pte;
- u64 __iomem *slot;
-
- /* XXX FIX ME XXX -- more efficient to keep a usage count */
- /* rather than scanning the second level page tables */
-
- for (pte = pg_tbl->entries + pg_tbl->num_simple_entries,
- slot = pg_tbl->base_slot + pg_tbl->num_simple_entries;
- pte < pg_tbl->entries + pg_tbl->config.total_entries;
- pte++, slot++) {
- if (pte->status == PTE_INUSE) {
- if (gasket_is_pte_range_free(
- pte->sublevel, GASKET_PAGES_PER_SUBTABLE))
- gasket_free_extended_subtable(
- pg_tbl, pte, slot);
- }
- }
+ if (gasket_addr_is_simple(pg_tbl, dev_addr))
+ return gasket_is_simple_dev_addr_bad(
+ pg_tbl, dev_addr, num_pages);
+ return gasket_is_extended_dev_addr_bad(pg_tbl, dev_addr, num_pages);
}
+EXPORT_SYMBOL(gasket_page_table_is_dev_addr_bad);
-/*
- * Convert (simple, page, offset) into a device address.
- * Examples:
- * Simple page 0, offset 32:
- * Input (0, 0, 32), Output 0x20
- * Simple page 1000, offset 511:
- * Input (0, 1000, 512), Output 0x3E81FF
- * Extended page 0, offset 32:
- * Input (0, 0, 32), Output 0x8000000020
- * Extended page 1000, offset 511:
- * Input (1, 1000, 512), Output 0x8003E81FF
- */
-static ulong gasket_components_to_dev_address(
- struct gasket_page_table *pg_tbl, int is_simple, uint page_index,
- uint offset)
+/* See gasket_page_table.h for description. */
+uint gasket_page_table_max_size(struct gasket_page_table *page_table)
{
- ulong lvl0_index, lvl1_index;
-
- if (is_simple) {
- /* Return simple addresses directly. */
- lvl0_index = page_index & (pg_tbl->config.total_entries - 1);
- return (lvl0_index << GASKET_SIMPLE_PAGE_SHIFT) | offset;
- }
-
- /*
- * This could be compressed into fewer statements, but
- * A) the compiler should optimize it
- * B) this is not slow
- * C) this is an uncommon operation
- * D) this is actually readable this way.
- */
- lvl0_index = page_index / GASKET_PAGES_PER_SUBTABLE;
- lvl1_index = page_index & (GASKET_PAGES_PER_SUBTABLE - 1);
- return (pg_tbl)->extended_flag |
- (lvl0_index << GASKET_EXTENDED_LVL0_SHIFT) |
- (lvl1_index << GASKET_EXTENDED_LVL1_SHIFT) | offset;
+ if (!page_table)
+ return 0;
+ return page_table->config.total_entries;
}
+EXPORT_SYMBOL(gasket_page_table_max_size);
-/*
- * Return the index of the page for the address in the simple table.
- * Does not perform validity checking.
- */
-static int gasket_simple_page_idx(
- struct gasket_page_table *pg_tbl, ulong dev_addr)
+/* See gasket_page_table.h for description. */
+uint gasket_page_table_num_entries(struct gasket_page_table *pg_tbl)
{
- return (dev_addr >> GASKET_SIMPLE_PAGE_SHIFT) &
- (pg_tbl->config.total_entries - 1);
+ if (!pg_tbl)
+ return 0;
+ return pg_tbl->num_simple_entries + pg_tbl->num_extended_entries;
}
+EXPORT_SYMBOL(gasket_page_table_num_entries);
-/*
- * Return the level 0 page index for the given address.
- * Does not perform validity checking.
- */
-static ulong gasket_extended_lvl0_page_idx(
- struct gasket_page_table *pg_tbl, ulong dev_addr)
+/* See gasket_page_table.h for description. */
+uint gasket_page_table_num_simple_entries(struct gasket_page_table *pg_tbl)
{
- return (dev_addr >> GASKET_EXTENDED_LVL0_SHIFT) &
- ((1 << GASKET_EXTENDED_LVL0_WIDTH) - 1);
+ if (!pg_tbl)
+ return 0;
+ return pg_tbl->num_simple_entries;
}
+EXPORT_SYMBOL(gasket_page_table_num_simple_entries);
-/*
- * Return the level 1 page index for the given address.
- * Does not perform validity checking.
- */
-static ulong gasket_extended_lvl1_page_idx(
- struct gasket_page_table *pg_tbl, ulong dev_addr)
+/* See gasket_page_table.h for description. */
+uint gasket_page_table_num_active_pages(struct gasket_page_table *pg_tbl)
{
- return (dev_addr >> GASKET_EXTENDED_LVL1_SHIFT) &
- (GASKET_PAGES_PER_SUBTABLE - 1);
+ if (!pg_tbl)
+ return 0;
+ return pg_tbl->num_active_pages;
}
+EXPORT_SYMBOL(gasket_page_table_num_active_pages);
-/*
- * Return whether a host buffer was mapped as coherent memory.
- *
- * A Gasket page_table currently support one contiguous dma range, mapped to one
- * contiguous virtual memory range. Check if the host_addr is within that range.
- */
-static int is_coherent(struct gasket_page_table *pg_tbl, ulong host_addr)
+/* See gasket_page_table.h */
+int gasket_page_table_system_status(struct gasket_page_table *page_table)
{
- u64 min, max;
-
- /* whether the host address is within user virt range */
- if (!pg_tbl->coherent_pages)
- return 0;
+ if (!page_table)
+ return GASKET_STATUS_LAMED;
- min = (u64)pg_tbl->coherent_pages[0].user_virt;
- max = min + PAGE_SIZE * pg_tbl->num_coherent_pages;
+ if (gasket_page_table_num_entries(page_table) == 0) {
+ dev_dbg(page_table->device, "Page table size is 0\n");
+ return GASKET_STATUS_LAMED;
+ }
- return min <= host_addr && host_addr < max;
+ return GASKET_STATUS_ALIVE;
}
/* Record the host_addr to coherent dma memory mapping. */
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 05/15] staging: gasket: TODO: remove entry for static function declarations
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
` (3 preceding siblings ...)
2018-07-31 20:24 ` [PATCH 04/15] staging: gasket: pg tbl: " Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 06/15] staging: gasket: core: fix function param line continuation style Todd Poynor
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
The static function declarations are removed, remove the TODO file entry
for this.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/TODO | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/staging/gasket/TODO b/drivers/staging/gasket/TODO
index 7f4c13ce021b..6aa2a7f6bc4b 100644
--- a/drivers/staging/gasket/TODO
+++ b/drivers/staging/gasket/TODO
@@ -1,6 +1,5 @@
This is a list of things that need to be done to get this driver out of the
staging directory.
-- Remove static function declarations.
- Document sysfs files with Documentation/ABI/ entries.
- Use misc interface instead of major number for driver version description.
- Add descriptions of module_param's
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 06/15] staging: gasket: core: fix function param line continuation style
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
` (4 preceding siblings ...)
2018-07-31 20:24 ` [PATCH 05/15] staging: gasket: TODO: remove entry for static function declarations Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 07/15] staging: gasket: ioctl: " Todd Poynor
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
Fix multi-line alignment formatting to look like:
int ret = long_function_name(device, VARIABLE1, VARIABLE2,
VARIABLE3, VARIABLE4);
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/gasket_core.c | 294 +++++++++++++--------------
drivers/staging/gasket/gasket_core.h | 68 +++----
2 files changed, 179 insertions(+), 183 deletions(-)
diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c
index b5a7254fbfb3..44344528cd88 100644
--- a/drivers/staging/gasket/gasket_core.c
+++ b/drivers/staging/gasket/gasket_core.c
@@ -103,8 +103,9 @@ enum gasket_sysfs_attribute_type {
};
/* Perform a standard Gasket callback. */
-static inline int check_and_invoke_callback(
- struct gasket_dev *gasket_dev, int (*cb_function)(struct gasket_dev *))
+static inline int
+check_and_invoke_callback(struct gasket_dev *gasket_dev,
+ int (*cb_function)(struct gasket_dev *))
{
int ret = 0;
@@ -119,8 +120,9 @@ static inline int check_and_invoke_callback(
}
/* Perform a standard Gasket callback without grabbing gasket_dev->mutex. */
-static inline int gasket_check_and_invoke_callback_nolock(
- struct gasket_dev *gasket_dev, int (*cb_function)(struct gasket_dev *))
+static inline int
+gasket_check_and_invoke_callback_nolock(struct gasket_dev *gasket_dev,
+ int (*cb_function)(struct gasket_dev *))
{
int ret = 0;
@@ -147,8 +149,8 @@ static int gasket_owned_by_current_tgid(struct gasket_cdev_info *info)
*
* Returns the located slot number on success or a negative number on failure.
*/
-static int gasket_find_dev_slot(
- struct gasket_internal_desc *internal_desc, const char *kobj_name)
+static int gasket_find_dev_slot(struct gasket_internal_desc *internal_desc,
+ const char *kobj_name)
{
int i;
@@ -186,9 +188,9 @@ static int gasket_find_dev_slot(
*
* Returns 0 if successful, a negative error code otherwise.
*/
-static int gasket_alloc_dev(
- struct gasket_internal_desc *internal_desc, struct device *parent,
- struct gasket_dev **pdev, const char *kobj_name)
+static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc,
+ struct device *parent, struct gasket_dev **pdev,
+ const char *kobj_name)
{
int dev_idx;
const struct gasket_driver_desc *driver_desc =
@@ -228,7 +230,7 @@ static int gasket_alloc_dev(
gasket_dev->dev_idx);
dev_info->devt =
MKDEV(driver_desc->major, driver_desc->minor +
- gasket_dev->dev_idx);
+ gasket_dev->dev_idx);
dev_info->device = device_create(internal_desc->class, parent,
dev_info->devt, gasket_dev, dev_info->name);
@@ -371,8 +373,8 @@ static void gasket_unmap_pci_bar(struct gasket_dev *dev, int bar_num)
*
* Returns 0 on success and a negative value otherwise.
*/
-static int gasket_setup_pci(
- struct pci_dev *pci_dev, struct gasket_dev *gasket_dev)
+static int gasket_setup_pci(struct pci_dev *pci_dev,
+ struct gasket_dev *gasket_dev)
{
int i, mapped_bars, ret;
@@ -421,8 +423,8 @@ static int gasket_get_hw_status(struct gasket_dev *gasket_dev)
const struct gasket_driver_desc *driver_desc =
gasket_dev->internal_desc->driver_desc;
- status = gasket_check_and_invoke_callback_nolock(
- gasket_dev, driver_desc->device_status_cb);
+ status = gasket_check_and_invoke_callback_nolock(gasket_dev,
+ driver_desc->device_status_cb);
if (status != GASKET_STATUS_ALIVE) {
dev_dbg(gasket_dev->dev, "Hardware reported status %d.\n",
status);
@@ -437,8 +439,7 @@ static int gasket_get_hw_status(struct gasket_dev *gasket_dev)
}
for (i = 0; i < driver_desc->num_page_tables; ++i) {
- status = gasket_page_table_system_status(
- gasket_dev->page_table[i]);
+ status = gasket_page_table_system_status(gasket_dev->page_table[i]);
if (status != GASKET_STATUS_ALIVE) {
dev_dbg(gasket_dev->dev,
"Page table %d reported status %d.\n",
@@ -450,8 +451,10 @@ static int gasket_get_hw_status(struct gasket_dev *gasket_dev)
return GASKET_STATUS_ALIVE;
}
-static ssize_t gasket_write_mappable_regions(
- char *buf, const struct gasket_driver_desc *driver_desc, int bar_index)
+static ssize_t
+gasket_write_mappable_regions(char *buf,
+ const struct gasket_driver_desc *driver_desc,
+ int bar_index)
{
int i;
ssize_t written;
@@ -478,8 +481,8 @@ static ssize_t gasket_write_mappable_regions(
return total_written;
}
-static ssize_t gasket_sysfs_data_show(
- struct device *device, struct device_attribute *attr, char *buf)
+static ssize_t gasket_sysfs_data_show(struct device *device,
+ struct device_attribute *attr, char *buf)
{
int i, ret = 0;
ssize_t current_written = 0;
@@ -532,54 +535,49 @@ static ssize_t gasket_sysfs_data_show(
}
break;
case ATTR_DRIVER_VERSION:
- ret = snprintf(
- buf, PAGE_SIZE, "%s\n",
- gasket_dev->internal_desc->driver_desc->driver_version);
+ ret = snprintf(buf, PAGE_SIZE, "%s\n",
+ gasket_dev->internal_desc->driver_desc->driver_version);
break;
case ATTR_FRAMEWORK_VERSION:
- ret = snprintf(
- buf, PAGE_SIZE, "%s\n", GASKET_FRAMEWORK_VERSION);
+ ret = snprintf(buf, PAGE_SIZE, "%s\n",
+ GASKET_FRAMEWORK_VERSION);
break;
case ATTR_DEVICE_TYPE:
- ret = snprintf(
- buf, PAGE_SIZE, "%s\n",
- gasket_dev->internal_desc->driver_desc->name);
+ ret = snprintf(buf, PAGE_SIZE, "%s\n",
+ gasket_dev->internal_desc->driver_desc->name);
break;
case ATTR_HARDWARE_REVISION:
- ret = snprintf(
- buf, PAGE_SIZE, "%d\n", gasket_dev->hardware_revision);
+ ret = snprintf(buf, PAGE_SIZE, "%d\n",
+ gasket_dev->hardware_revision);
break;
case ATTR_PCI_ADDRESS:
ret = snprintf(buf, PAGE_SIZE, "%s\n", gasket_dev->kobj_name);
break;
case ATTR_STATUS:
- ret = snprintf(
- buf, PAGE_SIZE, "%s\n",
- gasket_num_name_lookup(
- gasket_dev->status, gasket_status_name_table));
+ ret = snprintf(buf, PAGE_SIZE, "%s\n",
+ gasket_num_name_lookup(gasket_dev->status,
+ gasket_status_name_table));
break;
case ATTR_IS_DEVICE_OWNED:
- ret = snprintf(
- buf, PAGE_SIZE, "%d\n",
- gasket_dev->dev_info.ownership.is_owned);
+ ret = snprintf(buf, PAGE_SIZE, "%d\n",
+ gasket_dev->dev_info.ownership.is_owned);
break;
case ATTR_DEVICE_OWNER:
- ret = snprintf(
- buf, PAGE_SIZE, "%d\n",
- gasket_dev->dev_info.ownership.owner);
+ ret = snprintf(buf, PAGE_SIZE, "%d\n",
+ gasket_dev->dev_info.ownership.owner);
break;
case ATTR_WRITE_OPEN_COUNT:
- ret = snprintf(
- buf, PAGE_SIZE, "%d\n",
- gasket_dev->dev_info.ownership.write_open_count);
+ ret = snprintf(buf, PAGE_SIZE, "%d\n",
+ gasket_dev->dev_info.ownership.write_open_count);
break;
case ATTR_RESET_COUNT:
ret = snprintf(buf, PAGE_SIZE, "%d\n", gasket_dev->reset_count);
break;
case ATTR_USER_MEM_RANGES:
for (i = 0; i < GASKET_NUM_BARS; ++i) {
- current_written = gasket_write_mappable_regions(
- buf, driver_desc, i);
+ current_written =
+ gasket_write_mappable_regions(buf, driver_desc,
+ i);
buf += current_written;
ret += current_written;
}
@@ -622,9 +620,9 @@ static const struct gasket_sysfs_attribute gasket_sysfs_generic_attrs[] = {
};
/* Add a char device and related info. */
-static int gasket_add_cdev(
- struct gasket_cdev_info *dev_info,
- const struct file_operations *file_ops, struct module *owner)
+static int gasket_add_cdev(struct gasket_cdev_info *dev_info,
+ const struct file_operations *file_ops,
+ struct module *owner)
{
int ret;
@@ -672,8 +670,8 @@ static void gasket_disable_dev(struct gasket_dev *gasket_dev)
* Precondition: Called with g_mutex held (to avoid a race on return).
* Returns NULL if no matching device was found.
*/
-static struct gasket_internal_desc *lookup_internal_desc(
- struct pci_dev *pci_dev)
+static struct gasket_internal_desc *
+lookup_internal_desc(struct pci_dev *pci_dev)
{
int i;
@@ -693,9 +691,9 @@ static struct gasket_internal_desc *lookup_internal_desc(
* that the provided descriptor/range is of adequate size to hold the range to
* be mapped.
*/
-static bool gasket_mmap_has_permissions(
- struct gasket_dev *gasket_dev, struct vm_area_struct *vma,
- int bar_permissions)
+static bool gasket_mmap_has_permissions(struct gasket_dev *gasket_dev,
+ struct vm_area_struct *vma,
+ int bar_permissions)
{
int requested_permissions;
/* Always allow sysadmin to access. */
@@ -735,8 +733,9 @@ static bool gasket_mmap_has_permissions(
* Verifies that the input address is within the region allocated to coherent
* buffer.
*/
-static bool gasket_is_coherent_region(
- const struct gasket_driver_desc *driver_desc, ulong address)
+static bool
+gasket_is_coherent_region(const struct gasket_driver_desc *driver_desc,
+ ulong address)
{
struct gasket_coherent_buffer_desc coh_buff_desc =
driver_desc->coherent_buffer_description;
@@ -750,8 +749,8 @@ static bool gasket_is_coherent_region(
return false;
}
-static int gasket_get_bar_index(
- const struct gasket_dev *gasket_dev, ulong phys_addr)
+static int gasket_get_bar_index(const struct gasket_dev *gasket_dev,
+ ulong phys_addr)
{
int i;
const struct gasket_driver_desc *driver_desc;
@@ -786,10 +785,11 @@ static int gasket_get_bar_index(
*
* Returns true if there's anything to map, and false otherwise.
*/
-static bool gasket_mm_get_mapping_addrs(
- const struct gasket_mappable_region *region, ulong bar_offset,
- ulong requested_length, struct gasket_mappable_region *mappable_region,
- ulong *virt_offset)
+static bool
+gasket_mm_get_mapping_addrs(const struct gasket_mappable_region *region,
+ ulong bar_offset, ulong requested_length,
+ struct gasket_mappable_region *mappable_region,
+ ulong *virt_offset)
{
ulong range_start = region->start;
ulong range_length = region->length_bytes;
@@ -835,8 +835,8 @@ static bool gasket_mm_get_mapping_addrs(
*/
mappable_region->start = bar_offset;
*virt_offset = 0;
- mappable_region->length_bytes = min(
- requested_length, range_end - bar_offset);
+ mappable_region->length_bytes =
+ min(requested_length, range_end - bar_offset);
return true;
}
@@ -852,9 +852,9 @@ static bool gasket_mm_get_mapping_addrs(
* The offset is written into bar_offset on success.
* Returns zero on success, anything else on error.
*/
-static int gasket_mm_vma_bar_offset(
- const struct gasket_dev *gasket_dev, const struct vm_area_struct *vma,
- ulong *bar_offset)
+static int gasket_mm_vma_bar_offset(const struct gasket_dev *gasket_dev,
+ const struct vm_area_struct *vma,
+ ulong *bar_offset)
{
ulong raw_offset;
int bar_index;
@@ -877,9 +877,9 @@ static int gasket_mm_vma_bar_offset(
return 0;
}
-int gasket_mm_unmap_region(
- const struct gasket_dev *gasket_dev, struct vm_area_struct *vma,
- const struct gasket_mappable_region *map_region)
+int gasket_mm_unmap_region(const struct gasket_dev *gasket_dev,
+ struct vm_area_struct *vma,
+ const struct gasket_mappable_region *map_region)
{
ulong bar_offset;
ulong virt_offset;
@@ -893,9 +893,9 @@ int gasket_mm_unmap_region(
if (ret)
return ret;
- if (!gasket_mm_get_mapping_addrs(
- map_region, bar_offset, vma->vm_end - vma->vm_start,
- &mappable_region, &virt_offset))
+ if (!gasket_mm_get_mapping_addrs(map_region, bar_offset,
+ vma->vm_end - vma->vm_start,
+ &mappable_region, &virt_offset))
return 1;
/*
@@ -904,18 +904,17 @@ int gasket_mm_unmap_region(
*
* Next multiple of y: ceil_div(x, y) * y
*/
- zap_vma_ptes(
- vma, vma->vm_start + virt_offset,
- DIV_ROUND_UP(mappable_region.length_bytes, PAGE_SIZE) *
- PAGE_SIZE);
+ zap_vma_ptes(vma, vma->vm_start + virt_offset,
+ DIV_ROUND_UP(mappable_region.length_bytes, PAGE_SIZE) *
+ PAGE_SIZE);
return 0;
}
EXPORT_SYMBOL(gasket_mm_unmap_region);
/* Maps a virtual address + range to a physical offset of a BAR. */
-static enum do_map_region_status do_map_region(
- const struct gasket_dev *gasket_dev, struct vm_area_struct *vma,
- struct gasket_mappable_region *mappable_region)
+static enum do_map_region_status
+do_map_region(const struct gasket_dev *gasket_dev, struct vm_area_struct *vma,
+ struct gasket_mappable_region *mappable_region)
{
/* Maximum size of a single call to io_remap_pfn_range. */
/* I pulled this number out of thin air. */
@@ -944,10 +943,9 @@ static enum do_map_region_status do_map_region(
virt_base = vma->vm_start + virt_offset;
bar_index =
- gasket_get_bar_index(
- gasket_dev,
- (vma->vm_pgoff << PAGE_SHIFT) +
- driver_desc->legacy_mmap_address_offset);
+ gasket_get_bar_index(gasket_dev,
+ (vma->vm_pgoff << PAGE_SHIFT) +
+ driver_desc->legacy_mmap_address_offset);
phys_base = gasket_dev->bar_data[bar_index].phys_base + phys_offset;
while (mapped_bytes < map_length) {
/*
@@ -957,10 +955,10 @@ static enum do_map_region_status do_map_region(
chunk_size = min(max_chunk_size, map_length - mapped_bytes);
cond_resched();
- ret = io_remap_pfn_range(
- vma, virt_base + mapped_bytes,
- (phys_base + mapped_bytes) >> PAGE_SHIFT,
- chunk_size, vma->vm_page_prot);
+ ret = io_remap_pfn_range(vma, virt_base + mapped_bytes,
+ (phys_base + mapped_bytes) >>
+ PAGE_SHIFT, chunk_size,
+ vma->vm_page_prot);
if (ret) {
dev_err(gasket_dev->dev,
"Error remapping PFN range.\n");
@@ -984,8 +982,8 @@ static enum do_map_region_status do_map_region(
}
/* Map a region of coherent memory. */
-static int gasket_mmap_coherent(
- struct gasket_dev *gasket_dev, struct vm_area_struct *vma)
+static int gasket_mmap_coherent(struct gasket_dev *gasket_dev,
+ struct vm_area_struct *vma)
{
const struct gasket_driver_desc *driver_desc =
gasket_dev->internal_desc->driver_desc;
@@ -1008,10 +1006,9 @@ static int gasket_mmap_coherent(
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- ret = remap_pfn_range(
- vma, vma->vm_start,
- (gasket_dev->coherent_buffer.phys_base) >> PAGE_SHIFT,
- requested_length, vma->vm_page_prot);
+ ret = remap_pfn_range(vma, vma->vm_start,
+ (gasket_dev->coherent_buffer.phys_base) >>
+ PAGE_SHIFT, requested_length, vma->vm_page_prot);
if (ret) {
dev_err(gasket_dev->dev, "Error remapping PFN range err=%d.\n",
ret);
@@ -1022,9 +1019,9 @@ static int gasket_mmap_coherent(
/* Record the user virtual to dma_address mapping that was
* created by the kernel.
*/
- gasket_set_user_virt(
- gasket_dev, requested_length,
- gasket_dev->coherent_buffer.phys_base, vma->vm_start);
+ gasket_set_user_virt(gasket_dev, requested_length,
+ gasket_dev->coherent_buffer.phys_base,
+ vma->vm_start);
return 0;
}
@@ -1058,8 +1055,8 @@ static int gasket_mmap(struct file *filp, struct vm_area_struct *vma)
raw_offset = (vma->vm_pgoff << PAGE_SHIFT) +
driver_desc->legacy_mmap_address_offset;
vma_size = vma->vm_end - vma->vm_start;
- trace_gasket_mmap_entry(
- gasket_dev->dev_info.name, raw_offset, vma_size);
+ trace_gasket_mmap_entry(gasket_dev->dev_info.name, raw_offset,
+ vma_size);
/*
* Check if the raw offset is within a bar region. If not, check if it
@@ -1103,8 +1100,10 @@ static int gasket_mmap(struct file *filp, struct vm_area_struct *vma)
}
if (driver_desc->get_mappable_regions_cb) {
- ret = driver_desc->get_mappable_regions_cb(
- gasket_dev, bar_index, &map_regions, &num_map_regions);
+ ret = driver_desc->get_mappable_regions_cb(gasket_dev,
+ bar_index,
+ &map_regions,
+ &num_map_regions);
if (ret)
return ret;
} else {
@@ -1231,8 +1230,8 @@ static int gasket_open(struct inode *inode, struct file *filp)
/* If the node is not owned, assign it to the current TGID. */
if (!ownership->is_owned) {
- ret = gasket_check_and_invoke_callback_nolock(
- gasket_dev, driver_desc->device_open_cb);
+ ret = gasket_check_and_invoke_callback_nolock(gasket_dev,
+ driver_desc->device_open_cb);
if (ret) {
dev_err(gasket_dev->dev,
"Error in device open cb: %d\n", ret);
@@ -1298,16 +1297,14 @@ static int gasket_release(struct inode *inode, struct file *file)
driver_desc->device_reset_cb(gasket_dev, 0);
for (i = 0; i < driver_desc->num_page_tables; ++i) {
- gasket_page_table_unmap_all(
- gasket_dev->page_table[i]);
- gasket_page_table_garbage_collect(
- gasket_dev->page_table[i]);
+ gasket_page_table_unmap_all(gasket_dev->page_table[i]);
+ gasket_page_table_garbage_collect(gasket_dev->page_table[i]);
gasket_free_coherent_memory_all(gasket_dev, i);
}
/* Closes device, enters power save. */
- gasket_check_and_invoke_callback_nolock(
- gasket_dev, driver_desc->device_close_cb);
+ gasket_check_and_invoke_callback_nolock(gasket_dev,
+ driver_desc->device_close_cb);
}
}
@@ -1367,21 +1364,21 @@ static const struct file_operations gasket_file_ops = {
};
/* Perform final init and marks the device as active. */
-static int gasket_enable_dev(
- struct gasket_internal_desc *internal_desc,
- struct gasket_dev *gasket_dev)
+static int gasket_enable_dev(struct gasket_internal_desc *internal_desc,
+ struct gasket_dev *gasket_dev)
{
int tbl_idx;
int ret;
const struct gasket_driver_desc *driver_desc =
internal_desc->driver_desc;
- ret = gasket_interrupt_init(
- gasket_dev, driver_desc->name,
- driver_desc->interrupt_type, driver_desc->interrupts,
- driver_desc->num_interrupts, driver_desc->interrupt_pack_width,
- driver_desc->interrupt_bar_index,
- driver_desc->wire_interrupt_offsets);
+ ret = gasket_interrupt_init(gasket_dev, driver_desc->name,
+ driver_desc->interrupt_type,
+ driver_desc->interrupts,
+ driver_desc->num_interrupts,
+ driver_desc->interrupt_pack_width,
+ driver_desc->interrupt_bar_index,
+ driver_desc->wire_interrupt_offsets);
if (ret) {
dev_err(gasket_dev->dev,
"Critical failure to allocate interrupts: %d\n", ret);
@@ -1392,12 +1389,11 @@ static int gasket_enable_dev(
for (tbl_idx = 0; tbl_idx < driver_desc->num_page_tables; tbl_idx++) {
dev_dbg(gasket_dev->dev, "Initializing page table %d.\n",
tbl_idx);
- ret = gasket_page_table_init(
- &gasket_dev->page_table[tbl_idx],
- &gasket_dev->bar_data[
- driver_desc->page_table_bar_index],
- &driver_desc->page_table_configs[tbl_idx],
- gasket_dev->dev, gasket_dev->pci_dev);
+ ret = gasket_page_table_init(&gasket_dev->page_table[tbl_idx],
+ &gasket_dev->bar_data[driver_desc->page_table_bar_index],
+ &driver_desc->page_table_configs[tbl_idx],
+ gasket_dev->dev,
+ gasket_dev->pci_dev);
if (ret) {
dev_err(gasket_dev->dev,
"Couldn't init page table %d: %d\n",
@@ -1415,8 +1411,8 @@ static int gasket_enable_dev(
* hardware_revision_cb returns a positive integer (the rev) if
* successful.)
*/
- ret = check_and_invoke_callback(
- gasket_dev, driver_desc->hardware_revision_cb);
+ ret = check_and_invoke_callback(gasket_dev,
+ driver_desc->hardware_revision_cb);
if (ret < 0) {
dev_err(gasket_dev->dev,
"Error getting hardware revision: %d\n", ret);
@@ -1436,8 +1432,8 @@ static int gasket_enable_dev(
if (gasket_dev->status == GASKET_STATUS_DEAD)
dev_err(gasket_dev->dev, "Device reported as unhealthy.\n");
- ret = gasket_add_cdev(
- &gasket_dev->dev_info, &gasket_file_ops, driver_desc->module);
+ ret = gasket_add_cdev(&gasket_dev->dev_info, &gasket_file_ops,
+ driver_desc->module);
if (ret)
return ret;
@@ -1452,8 +1448,8 @@ static int gasket_enable_dev(
*
* Returns 0 if successful and a negative value otherwise.
*/
-static int gasket_pci_probe(
- struct pci_dev *pci_dev, const struct pci_device_id *id)
+static int gasket_pci_probe(struct pci_dev *pci_dev,
+ const struct pci_device_id *id)
{
int ret;
const char *kobj_name = dev_name(&pci_dev->dev);
@@ -1497,8 +1493,8 @@ static int gasket_pci_probe(
goto fail2;
}
- ret = gasket_sysfs_create_mapping(
- gasket_dev->dev_info.device, gasket_dev);
+ ret = gasket_sysfs_create_mapping(gasket_dev->dev_info.device,
+ gasket_dev);
if (ret)
goto fail3;
@@ -1513,13 +1509,13 @@ static int gasket_pci_probe(
"Cannot create sysfs pci link: %d\n", ret);
goto fail3;
}
- ret = gasket_sysfs_create_entries(
- gasket_dev->dev_info.device, gasket_sysfs_generic_attrs);
+ ret = gasket_sysfs_create_entries(gasket_dev->dev_info.device,
+ gasket_sysfs_generic_attrs);
if (ret)
goto fail4;
- ret = check_and_invoke_callback(
- gasket_dev, driver_desc->sysfs_setup_cb);
+ ret = check_and_invoke_callback(gasket_dev,
+ driver_desc->sysfs_setup_cb);
if (ret) {
dev_err(gasket_dev->dev, "Error in sysfs setup cb: %d\n", ret);
goto fail5;
@@ -1611,8 +1607,8 @@ static void gasket_pci_remove(struct pci_dev *pci_dev)
*
* The table must have a NULL name pointer at the end.
*/
-const char *gasket_num_name_lookup(
- uint num, const struct gasket_num_name *table)
+const char *gasket_num_name_lookup(uint num,
+ const struct gasket_num_name *table)
{
uint i = 0;
@@ -1677,8 +1673,8 @@ int gasket_reset_nolock(struct gasket_dev *gasket_dev, uint reset_type)
}
EXPORT_SYMBOL(gasket_reset_nolock);
-gasket_ioctl_permissions_cb_t gasket_get_ioctl_permissions_cb(
- struct gasket_dev *gasket_dev)
+gasket_ioctl_permissions_cb_t
+gasket_get_ioctl_permissions_cb(struct gasket_dev *gasket_dev)
{
return gasket_dev->internal_desc->driver_desc->ioctl_permissions_cb;
}
@@ -1713,9 +1709,9 @@ struct device *gasket_get_device(struct gasket_dev *dev)
* Description: Busy waits for a specific combination of bits to be set on a
* Gasket register.
**/
-int gasket_wait_with_reschedule(
- struct gasket_dev *gasket_dev, int bar, u64 offset, u64 mask, u64 val,
- uint max_retries, u64 delay_ms)
+int gasket_wait_with_reschedule(struct gasket_dev *gasket_dev, int bar,
+ u64 offset, u64 mask, u64 val,
+ uint max_retries, u64 delay_ms)
{
uint retries = 0;
u64 tmp;
@@ -1797,17 +1793,17 @@ int gasket_register_device(const struct gasket_driver_desc *driver_desc)
* depends on KBUILD_MODNAME, and this is a shared file.
*/
pr_debug("Registering PCI driver.\n");
- ret = __pci_register_driver(
- &internal->pci, driver_desc->module, driver_desc->name);
+ ret = __pci_register_driver(&internal->pci, driver_desc->module,
+ driver_desc->name);
if (ret) {
pr_err("cannot register pci driver [ret=%d]\n", ret);
goto fail1;
}
pr_debug("Registering char driver.\n");
- ret = register_chrdev_region(
- MKDEV(driver_desc->major, driver_desc->minor), GASKET_DEV_MAX,
- driver_desc->name);
+ ret = register_chrdev_region(MKDEV(driver_desc->major,
+ driver_desc->minor), GASKET_DEV_MAX,
+ driver_desc->name);
if (ret) {
pr_err("cannot register char driver [ret=%d]\n", ret);
goto fail2;
@@ -1853,8 +1849,8 @@ void gasket_unregister_device(const struct gasket_driver_desc *driver_desc)
return;
}
- unregister_chrdev_region(
- MKDEV(driver_desc->major, driver_desc->minor), GASKET_DEV_MAX);
+ unregister_chrdev_region(MKDEV(driver_desc->major, driver_desc->minor),
+ GASKET_DEV_MAX);
pci_unregister_driver(&internal_desc->pci);
diff --git a/drivers/staging/gasket/gasket_core.h b/drivers/staging/gasket/gasket_core.h
index 8bd431ad3b58..713bf42de41a 100644
--- a/drivers/staging/gasket/gasket_core.h
+++ b/drivers/staging/gasket/gasket_core.h
@@ -318,11 +318,11 @@ struct gasket_dev {
};
/* Type of the ioctl handler callback. */
-typedef long (*gasket_ioctl_handler_cb_t)
- (struct file *file, uint cmd, void __user *argp);
+typedef long (*gasket_ioctl_handler_cb_t)(struct file *file, uint cmd,
+ void __user *argp);
/* Type of the ioctl permissions check callback. See below. */
-typedef int (*gasket_ioctl_permissions_cb_t)(
- struct file *filp, uint cmd, void __user *argp);
+typedef int (*gasket_ioctl_permissions_cb_t)(struct file *filp, uint cmd,
+ void __user *argp);
/*
* Device type descriptor.
@@ -457,8 +457,8 @@ struct gasket_driver_desc {
* descriptor for an open file is closed. This call is intended to
* handle any per-user or per-fd cleanup.
*/
- int (*device_release_cb)(
- struct gasket_dev *gasket_dev, struct file *file);
+ int (*device_release_cb)(struct gasket_dev *gasket_dev,
+ struct file *file);
/*
* device_close_cb: Callback for when a device node is closed for the
@@ -527,10 +527,10 @@ struct gasket_driver_desc {
* information is then compared to mmap request to determine which
* regions to actually map.
*/
- int (*get_mappable_regions_cb)(
- struct gasket_dev *gasket_dev, int bar_index,
- struct gasket_mappable_region **mappable_regions,
- int *num_mappable_regions);
+ int (*get_mappable_regions_cb)(struct gasket_dev *gasket_dev,
+ int bar_index,
+ struct gasket_mappable_region **mappable_regions,
+ int *num_mappable_regions);
/*
* ioctl_permissions_cb: Check permissions for generic ioctls.
@@ -631,16 +631,16 @@ int gasket_reset_nolock(struct gasket_dev *gasket_dev, uint reset_type);
*/
/* Unmaps the specified mappable region from a VMA. */
-int gasket_mm_unmap_region(
- const struct gasket_dev *gasket_dev, struct vm_area_struct *vma,
- const struct gasket_mappable_region *map_region);
+int gasket_mm_unmap_region(const struct gasket_dev *gasket_dev,
+ struct vm_area_struct *vma,
+ const struct gasket_mappable_region *map_region);
/*
* Get the ioctl permissions callback.
* @gasket_dev: Gasket device structure.
*/
-gasket_ioctl_permissions_cb_t gasket_get_ioctl_permissions_cb(
- struct gasket_dev *gasket_dev);
+gasket_ioctl_permissions_cb_t
+gasket_get_ioctl_permissions_cb(struct gasket_dev *gasket_dev);
/**
* Lookup a name by number in a num_name table.
@@ -648,37 +648,37 @@ gasket_ioctl_permissions_cb_t gasket_get_ioctl_permissions_cb(
* @table: Array of num_name structures, the table for the lookup.
*
*/
-const char *gasket_num_name_lookup(
- uint num, const struct gasket_num_name *table);
+const char *gasket_num_name_lookup(uint num,
+ const struct gasket_num_name *table);
/* Handy inlines */
-static inline ulong gasket_dev_read_64(
- struct gasket_dev *gasket_dev, int bar, ulong location)
+static inline ulong gasket_dev_read_64(struct gasket_dev *gasket_dev, int bar,
+ ulong location)
{
return readq(&gasket_dev->bar_data[bar].virt_base[location]);
}
-static inline void gasket_dev_write_64(
- struct gasket_dev *dev, u64 value, int bar, ulong location)
+static inline void gasket_dev_write_64(struct gasket_dev *dev, u64 value,
+ int bar, ulong location)
{
writeq(value, &dev->bar_data[bar].virt_base[location]);
}
-static inline void gasket_dev_write_32(
- struct gasket_dev *dev, u32 value, int bar, ulong location)
+static inline void gasket_dev_write_32(struct gasket_dev *dev, u32 value,
+ int bar, ulong location)
{
writel(value, &dev->bar_data[bar].virt_base[location]);
}
-static inline u32 gasket_dev_read_32(
- struct gasket_dev *dev, int bar, ulong location)
+static inline u32 gasket_dev_read_32(struct gasket_dev *dev, int bar,
+ ulong location)
{
return readl(&dev->bar_data[bar].virt_base[location]);
}
-static inline void gasket_read_modify_write_64(
- struct gasket_dev *dev, int bar, ulong location, u64 value,
- u64 mask_width, u64 mask_shift)
+static inline void gasket_read_modify_write_64(struct gasket_dev *dev, int bar,
+ ulong location, u64 value,
+ u64 mask_width, u64 mask_shift)
{
u64 mask, tmp;
@@ -688,9 +688,9 @@ static inline void gasket_read_modify_write_64(
gasket_dev_write_64(dev, tmp, bar, location);
}
-static inline void gasket_read_modify_write_32(
- struct gasket_dev *dev, int bar, ulong location, u32 value,
- u32 mask_width, u32 mask_shift)
+static inline void gasket_read_modify_write_32(struct gasket_dev *dev, int bar,
+ ulong location, u32 value,
+ u32 mask_width, u32 mask_shift)
{
u32 mask, tmp;
@@ -707,8 +707,8 @@ const struct gasket_driver_desc *gasket_get_driver_desc(struct gasket_dev *dev);
struct device *gasket_get_device(struct gasket_dev *dev);
/* Helper function, Asynchronous waits on a given set of bits. */
-int gasket_wait_with_reschedule(
- struct gasket_dev *gasket_dev, int bar, u64 offset, u64 mask, u64 val,
- uint max_retries, u64 delay_ms);
+int gasket_wait_with_reschedule(struct gasket_dev *gasket_dev, int bar,
+ u64 offset, u64 mask, u64 val,
+ uint max_retries, u64 delay_ms);
#endif /* __GASKET_CORE_H__ */
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 07/15] staging: gasket: ioctl: fix function param line continuation style
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
` (5 preceding siblings ...)
2018-07-31 20:24 ` [PATCH 06/15] staging: gasket: core: fix function param line continuation style Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 08/15] staging: gasket: page table: " Todd Poynor
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
Fix multi-line alignment formatting to look like:
int ret = long_function_name(device, VARIABLE1, VARIABLE2,
VARIABLE3, VARIABLE4);
Many of these TODO items were previously cleaned up during the conversion
to standard logging functions.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/gasket_ioctl.c | 60 +++++++++++++--------------
1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/drivers/staging/gasket/gasket_ioctl.c b/drivers/staging/gasket/gasket_ioctl.c
index 134d45a281ac..d3397cc74e69 100644
--- a/drivers/staging/gasket/gasket_ioctl.c
+++ b/drivers/staging/gasket/gasket_ioctl.c
@@ -79,12 +79,12 @@ static int gasket_read_simple_page_table_size(
if (ibuf.page_table_index >= gasket_dev->num_page_tables)
return -EFAULT;
- ibuf.size = gasket_page_table_num_simple_entries(
- gasket_dev->page_table[ibuf.page_table_index]);
+ ibuf.size =
+ gasket_page_table_num_simple_entries(gasket_dev->page_table[ibuf.page_table_index]);
- trace_gasket_ioctl_page_table_data(
- ibuf.page_table_index, ibuf.size, ibuf.host_address,
- ibuf.device_address);
+ trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size,
+ ibuf.host_address,
+ ibuf.device_address);
if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
return -EFAULT;
@@ -138,21 +138,21 @@ static int gasket_map_buffers(struct gasket_dev *gasket_dev,
if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
return -EFAULT;
- trace_gasket_ioctl_page_table_data(
- ibuf.page_table_index, ibuf.size, ibuf.host_address,
- ibuf.device_address);
+ trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size,
+ ibuf.host_address,
+ ibuf.device_address);
if (ibuf.page_table_index >= gasket_dev->num_page_tables)
return -EFAULT;
- if (gasket_page_table_are_addrs_bad(
- gasket_dev->page_table[ibuf.page_table_index],
- ibuf.host_address, ibuf.device_address, ibuf.size))
+ if (gasket_page_table_are_addrs_bad(gasket_dev->page_table[ibuf.page_table_index],
+ ibuf.host_address,
+ ibuf.device_address, ibuf.size))
return -EINVAL;
- return gasket_page_table_map(
- gasket_dev->page_table[ibuf.page_table_index],
- ibuf.host_address, ibuf.device_address, ibuf.size / PAGE_SIZE);
+ return gasket_page_table_map(gasket_dev->page_table[ibuf.page_table_index],
+ ibuf.host_address, ibuf.device_address,
+ ibuf.size / PAGE_SIZE);
}
/* Unmap a userspace buffer from a device virtual address. */
@@ -164,16 +164,15 @@ static int gasket_unmap_buffers(struct gasket_dev *gasket_dev,
if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
return -EFAULT;
- trace_gasket_ioctl_page_table_data(
- ibuf.page_table_index, ibuf.size, ibuf.host_address,
- ibuf.device_address);
+ trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size,
+ ibuf.host_address,
+ ibuf.device_address);
if (ibuf.page_table_index >= gasket_dev->num_page_tables)
return -EFAULT;
- if (gasket_page_table_is_dev_addr_bad(
- gasket_dev->page_table[ibuf.page_table_index],
- ibuf.device_address, ibuf.size))
+ if (gasket_page_table_is_dev_addr_bad(gasket_dev->page_table[ibuf.page_table_index],
+ ibuf.device_address, ibuf.size))
return -EINVAL;
gasket_page_table_unmap(gasket_dev->page_table[ibuf.page_table_index],
@@ -197,8 +196,8 @@ static int gasket_config_coherent_allocator(
sizeof(struct gasket_coherent_alloc_config_ioctl)))
return -EFAULT;
- trace_gasket_ioctl_config_coherent_allocator(
- ibuf.enable, ibuf.size, ibuf.dma_address);
+ trace_gasket_ioctl_config_coherent_allocator(ibuf.enable, ibuf.size,
+ ibuf.dma_address);
if (ibuf.page_table_index >= gasket_dev->num_page_tables)
return -EFAULT;
@@ -207,13 +206,13 @@ static int gasket_config_coherent_allocator(
return -ENOMEM;
if (ibuf.enable == 0) {
- ret = gasket_free_coherent_memory(
- gasket_dev, ibuf.size, ibuf.dma_address,
- ibuf.page_table_index);
+ ret = gasket_free_coherent_memory(gasket_dev, ibuf.size,
+ ibuf.dma_address,
+ ibuf.page_table_index);
} else {
- ret = gasket_alloc_coherent_memory(
- gasket_dev, ibuf.size, &ibuf.dma_address,
- ibuf.page_table_index);
+ ret = gasket_alloc_coherent_memory(gasket_dev, ibuf.size,
+ &ibuf.dma_address,
+ ibuf.page_table_index);
}
if (ret)
return ret;
@@ -313,8 +312,9 @@ long gasket_handle_ioctl(struct file *filp, uint cmd, void __user *argp)
break;
case GASKET_IOCTL_CLEAR_EVENTFD:
trace_gasket_ioctl_integer_data(arg);
- retval = gasket_interrupt_clear_eventfd(
- gasket_dev->interrupt_data, (int)arg);
+ retval =
+ gasket_interrupt_clear_eventfd(gasket_dev->interrupt_data,
+ (int)arg);
break;
case GASKET_IOCTL_PARTITION_PAGE_TABLE:
trace_gasket_ioctl_integer_data(arg);
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 08/15] staging: gasket: page table: fix function param line continuation style
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
` (6 preceding siblings ...)
2018-07-31 20:24 ` [PATCH 07/15] staging: gasket: ioctl: " Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 09/15] staging: gasket: sysfs: " Todd Poynor
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
Fix multi-line alignment formatting to look like:
int ret = long_function_name(device, VARIABLE1, VARIABLE2,
VARIABLE3, VARIABLE4);
Many of these TODO items were previously cleaned up during the conversion
to standard logging functions.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/gasket_page_table.c | 206 +++++++++++----------
drivers/staging/gasket/gasket_page_table.h | 33 ++--
2 files changed, 120 insertions(+), 119 deletions(-)
diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c
index aa036b2e8193..13e1d0952a47 100644
--- a/drivers/staging/gasket/gasket_page_table.c
+++ b/drivers/staging/gasket/gasket_page_table.c
@@ -215,11 +215,10 @@ struct gasket_page_table {
};
/* See gasket_page_table.h for description. */
-int gasket_page_table_init(
- struct gasket_page_table **ppg_tbl,
- const struct gasket_bar_data *bar_data,
- const struct gasket_page_table_config *page_table_config,
- struct device *device, struct pci_dev *pci_dev)
+int gasket_page_table_init(struct gasket_page_table **ppg_tbl,
+ const struct gasket_bar_data *bar_data,
+ const struct gasket_page_table_config *page_table_config,
+ struct device *device, struct pci_dev *pci_dev)
{
ulong bytes;
struct gasket_page_table *pg_tbl;
@@ -276,10 +275,10 @@ int gasket_page_table_init(
pg_tbl->extended_flag = 0;
}
pg_tbl->num_active_pages = 0;
- pg_tbl->base_slot = (u64 __iomem *)&(
- bar_data->virt_base[page_table_config->base_reg]);
- pg_tbl->extended_offset_reg = (u64 __iomem *)&(
- bar_data->virt_base[page_table_config->extended_reg]);
+ pg_tbl->base_slot =
+ (u64 __iomem *)&bar_data->virt_base[page_table_config->base_reg];
+ pg_tbl->extended_offset_reg =
+ (u64 __iomem *)&bar_data->virt_base[page_table_config->extended_reg];
pg_tbl->device = get_device(device);
pg_tbl->pci_dev = pci_dev_get(pci_dev);
@@ -292,8 +291,8 @@ int gasket_page_table_init(
* Check if a range of PTEs is free.
* The page table mutex must be held by the caller.
*/
-static bool gasket_is_pte_range_free(
- struct gasket_page_table_entry *ptes, uint num_entries)
+static bool gasket_is_pte_range_free(struct gasket_page_table_entry *ptes,
+ uint num_entries)
{
int i;
@@ -309,9 +308,9 @@ static bool gasket_is_pte_range_free(
* Free a second level page [sub]table.
* The page table mutex must be held before this call.
*/
-static void gasket_free_extended_subtable(
- struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *pte,
- u64 __iomem *slot)
+static void gasket_free_extended_subtable(struct gasket_page_table *pg_tbl,
+ struct gasket_page_table_entry *pte,
+ u64 __iomem *slot)
{
/* Release the page table from the driver */
pte->status = PTE_FREE;
@@ -337,8 +336,8 @@ static void gasket_free_extended_subtable(
* Actually perform collection.
* The page table mutex must be held by the caller.
*/
-static void gasket_page_table_garbage_collect_nolock(
- struct gasket_page_table *pg_tbl)
+static void
+gasket_page_table_garbage_collect_nolock(struct gasket_page_table *pg_tbl)
{
struct gasket_page_table_entry *pte;
u64 __iomem *slot;
@@ -351,10 +350,10 @@ static void gasket_page_table_garbage_collect_nolock(
pte < pg_tbl->entries + pg_tbl->config.total_entries;
pte++, slot++) {
if (pte->status == PTE_INUSE) {
- if (gasket_is_pte_range_free(
- pte->sublevel, GASKET_PAGES_PER_SUBTABLE))
- gasket_free_extended_subtable(
- pg_tbl, pte, slot);
+ if (gasket_is_pte_range_free(pte->sublevel,
+ GASKET_PAGES_PER_SUBTABLE))
+ gasket_free_extended_subtable(pg_tbl, pte,
+ slot);
}
}
}
@@ -384,8 +383,8 @@ void gasket_page_table_cleanup(struct gasket_page_table *pg_tbl)
}
/* See gasket_page_table.h for description. */
-int gasket_page_table_partition(
- struct gasket_page_table *pg_tbl, uint num_simple_entries)
+int gasket_page_table_partition(struct gasket_page_table *pg_tbl,
+ uint num_simple_entries)
{
int i, start;
@@ -445,10 +444,10 @@ static int is_coherent(struct gasket_page_table *pg_tbl, ulong host_addr)
* an extended mapping, these will be within a second-level page table
* allocated by the host and so must have their __iomem attribute casted away.
*/
-static int gasket_perform_mapping(
- struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *ptes,
- u64 __iomem *slots, ulong host_addr, uint num_pages,
- int is_simple_mapping)
+static int gasket_perform_mapping(struct gasket_page_table *pg_tbl,
+ struct gasket_page_table_entry *ptes,
+ u64 __iomem *slots, ulong host_addr,
+ uint num_pages, int is_simple_mapping)
{
int ret;
ulong offset;
@@ -470,8 +469,8 @@ static int gasket_perform_mapping(
ptes[i].dma_addr = pg_tbl->coherent_pages[0].paddr +
off + i * PAGE_SIZE;
} else {
- ret = get_user_pages_fast(
- page_addr - offset, 1, 1, &page);
+ ret = get_user_pages_fast(page_addr - offset, 1, 1,
+ &page);
if (ret <= 0) {
dev_err(pg_tbl->device,
@@ -532,8 +531,8 @@ static int gasket_perform_mapping(
* Return the index of the page for the address in the simple table.
* Does not perform validity checking.
*/
-static int gasket_simple_page_idx(
- struct gasket_page_table *pg_tbl, ulong dev_addr)
+static int gasket_simple_page_idx(struct gasket_page_table *pg_tbl,
+ ulong dev_addr)
{
return (dev_addr >> GASKET_SIMPLE_PAGE_SHIFT) &
(pg_tbl->config.total_entries - 1);
@@ -543,8 +542,8 @@ static int gasket_simple_page_idx(
* Return the level 0 page index for the given address.
* Does not perform validity checking.
*/
-static ulong gasket_extended_lvl0_page_idx(
- struct gasket_page_table *pg_tbl, ulong dev_addr)
+static ulong gasket_extended_lvl0_page_idx(struct gasket_page_table *pg_tbl,
+ ulong dev_addr)
{
return (dev_addr >> GASKET_EXTENDED_LVL0_SHIFT) &
((1 << GASKET_EXTENDED_LVL0_WIDTH) - 1);
@@ -554,8 +553,8 @@ static ulong gasket_extended_lvl0_page_idx(
* Return the level 1 page index for the given address.
* Does not perform validity checking.
*/
-static ulong gasket_extended_lvl1_page_idx(
- struct gasket_page_table *pg_tbl, ulong dev_addr)
+static ulong gasket_extended_lvl1_page_idx(struct gasket_page_table *pg_tbl,
+ ulong dev_addr)
{
return (dev_addr >> GASKET_EXTENDED_LVL1_SHIFT) &
(GASKET_PAGES_PER_SUBTABLE - 1);
@@ -565,12 +564,12 @@ static ulong gasket_extended_lvl1_page_idx(
* Allocate page table entries in a simple table.
* The page table mutex must be held by the caller.
*/
-static int gasket_alloc_simple_entries(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+static int gasket_alloc_simple_entries(struct gasket_page_table *pg_tbl,
+ ulong dev_addr, uint num_pages)
{
- if (!gasket_is_pte_range_free(
- pg_tbl->entries + gasket_simple_page_idx(pg_tbl, dev_addr),
- num_pages))
+ if (!gasket_is_pte_range_free(pg_tbl->entries +
+ gasket_simple_page_idx(pg_tbl, dev_addr),
+ num_pages))
return -EBUSY;
return 0;
@@ -593,9 +592,10 @@ static bool gasket_release_page(struct page *page)
* Unmap and release mapped pages.
* The page table mutex must be held by the caller.
*/
-static void gasket_perform_unmapping(
- struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *ptes,
- u64 __iomem *slots, uint num_pages, int is_simple_mapping)
+static void gasket_perform_unmapping(struct gasket_page_table *pg_tbl,
+ struct gasket_page_table_entry *ptes,
+ u64 __iomem *slots, uint num_pages,
+ int is_simple_mapping)
{
int i;
/*
@@ -631,8 +631,8 @@ static void gasket_perform_unmapping(
* Unmap and release pages mapped to simple addresses.
* The page table mutex must be held by the caller.
*/
-static void gasket_unmap_simple_pages(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+static void gasket_unmap_simple_pages(struct gasket_page_table *pg_tbl,
+ ulong dev_addr, uint num_pages)
{
uint slot = gasket_simple_page_idx(pg_tbl, dev_addr);
@@ -644,8 +644,8 @@ static void gasket_unmap_simple_pages(
* Unmap and release buffers to extended addresses.
* The page table mutex must be held by the caller.
*/
-static void gasket_unmap_extended_pages(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+static void gasket_unmap_extended_pages(struct gasket_page_table *pg_tbl,
+ ulong dev_addr, uint num_pages)
{
uint slot_idx, remain, len;
struct gasket_page_table_entry *pte;
@@ -663,9 +663,9 @@ static void gasket_unmap_extended_pages(
if (pte->status == PTE_INUSE) {
slot_base = (u64 __iomem *)(page_address(pte->page) +
pte->offset);
- gasket_perform_unmapping(
- pg_tbl, pte->sublevel + slot_idx,
- slot_base + slot_idx, len, 0);
+ gasket_perform_unmapping(pg_tbl,
+ pte->sublevel + slot_idx,
+ slot_base + slot_idx, len, 0);
}
remain -= len;
@@ -675,8 +675,8 @@ static void gasket_unmap_extended_pages(
}
/* Evaluates to nonzero if the specified virtual address is simple. */
-static inline bool gasket_addr_is_simple(
- struct gasket_page_table *pg_tbl, ulong addr)
+static inline bool gasket_addr_is_simple(struct gasket_page_table *pg_tbl,
+ ulong addr)
{
return !((addr) & (pg_tbl)->extended_flag);
}
@@ -693,9 +693,9 @@ static inline bool gasket_addr_is_simple(
* Extended page 1000, offset 511:
* Input (1, 1000, 512), Output 0x8003E81FF
*/
-static ulong gasket_components_to_dev_address(
- struct gasket_page_table *pg_tbl, int is_simple, uint page_index,
- uint offset)
+static ulong gasket_components_to_dev_address(struct gasket_page_table *pg_tbl,
+ int is_simple, uint page_index,
+ uint offset)
{
ulong lvl0_index, lvl1_index;
@@ -726,15 +726,15 @@ static ulong gasket_components_to_dev_address(
* and that the requested page range starts and ends within the set of
* currently-partitioned simple pages.
*/
-static bool gasket_is_simple_dev_addr_bad(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+static bool gasket_is_simple_dev_addr_bad(struct gasket_page_table *pg_tbl,
+ ulong dev_addr, uint num_pages)
{
ulong page_offset = dev_addr & (PAGE_SIZE - 1);
ulong page_index =
(dev_addr / PAGE_SIZE) & (pg_tbl->config.total_entries - 1);
- if (gasket_components_to_dev_address(
- pg_tbl, 1, page_index, page_offset) != dev_addr) {
+ if (gasket_components_to_dev_address(pg_tbl, 1, page_index,
+ page_offset) != dev_addr) {
dev_err(pg_tbl->device, "address is invalid, 0x%lX\n",
dev_addr);
return true;
@@ -764,8 +764,8 @@ static bool gasket_is_simple_dev_addr_bad(
* offset) and that the requested page range starts and ends within the set of
* currently-partitioned extended pages.
*/
-static bool gasket_is_extended_dev_addr_bad(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+static bool gasket_is_extended_dev_addr_bad(struct gasket_page_table *pg_tbl,
+ ulong dev_addr, uint num_pages)
{
/* Starting byte index of dev_addr into the first mapped page */
ulong page_offset = dev_addr & (PAGE_SIZE - 1);
@@ -792,8 +792,8 @@ static bool gasket_is_extended_dev_addr_bad(
num_lvl0_pages = (num_pages + GASKET_PAGES_PER_SUBTABLE - 1) /
GASKET_PAGES_PER_SUBTABLE;
- if (gasket_components_to_dev_address(
- pg_tbl, 0, page_global_idx, page_offset) != dev_addr) {
+ if (gasket_components_to_dev_address(pg_tbl, 0, page_global_idx,
+ page_offset) != dev_addr) {
dev_err(pg_tbl->device, "address is invalid: 0x%lx\n",
dev_addr);
return true;
@@ -821,8 +821,8 @@ static bool gasket_is_extended_dev_addr_bad(
* Non-locking entry to unmapping routines.
* The page table mutex must be held by the caller.
*/
-static void gasket_page_table_unmap_nolock(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+static void gasket_page_table_unmap_nolock(struct gasket_page_table *pg_tbl,
+ ulong dev_addr, uint num_pages)
{
if (!num_pages)
return;
@@ -837,9 +837,9 @@ static void gasket_page_table_unmap_nolock(
* Allocate and map pages to simple addresses.
* If there is an error, no pages are mapped.
*/
-static int gasket_map_simple_pages(
- struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr,
- uint num_pages)
+static int gasket_map_simple_pages(struct gasket_page_table *pg_tbl,
+ ulong host_addr, ulong dev_addr,
+ uint num_pages)
{
int ret;
uint slot_idx = gasket_simple_page_idx(pg_tbl, dev_addr);
@@ -852,9 +852,9 @@ static int gasket_map_simple_pages(
return ret;
}
- ret = gasket_perform_mapping(
- pg_tbl, pg_tbl->entries + slot_idx,
- pg_tbl->base_slot + slot_idx, host_addr, num_pages, 1);
+ ret = gasket_perform_mapping(pg_tbl, pg_tbl->entries + slot_idx,
+ pg_tbl->base_slot + slot_idx, host_addr,
+ num_pages, 1);
if (ret) {
gasket_page_table_unmap_nolock(pg_tbl, dev_addr, num_pages);
@@ -867,9 +867,9 @@ static int gasket_map_simple_pages(
* Allocate a second level page table.
* The page table mutex must be held by the caller.
*/
-static int gasket_alloc_extended_subtable(
- struct gasket_page_table *pg_tbl, struct gasket_page_table_entry *pte,
- u64 __iomem *slot)
+static int gasket_alloc_extended_subtable(struct gasket_page_table *pg_tbl,
+ struct gasket_page_table_entry *pte,
+ u64 __iomem *slot)
{
ulong page_addr, subtable_bytes;
dma_addr_t dma_addr;
@@ -924,8 +924,8 @@ static int gasket_alloc_extended_subtable(
*
* The page table mutex must be held by the caller.
*/
-static int gasket_alloc_extended_entries(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_entries)
+static int gasket_alloc_extended_entries(struct gasket_page_table *pg_tbl,
+ ulong dev_addr, uint num_entries)
{
int ret = 0;
uint remain, subtable_slot_idx, len;
@@ -951,8 +951,8 @@ static int gasket_alloc_extended_entries(
return ret;
}
} else {
- if (!gasket_is_pte_range_free(
- pte->sublevel + subtable_slot_idx, len))
+ if (!gasket_is_pte_range_free(pte->sublevel +
+ subtable_slot_idx, len))
return -EBUSY;
}
@@ -969,9 +969,9 @@ static int gasket_alloc_extended_entries(
* gasket_map_extended_pages - Get and map buffers to extended addresses.
* If there is an error, no pages are mapped.
*/
-static int gasket_map_extended_pages(
- struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr,
- uint num_pages)
+static int gasket_map_extended_pages(struct gasket_page_table *pg_tbl,
+ ulong host_addr, ulong dev_addr,
+ uint num_pages)
{
int ret;
ulong dev_addr_end;
@@ -1003,12 +1003,12 @@ static int gasket_map_extended_pages(
slot_base =
(u64 __iomem *)(page_address(pte->page) + pte->offset);
- ret = gasket_perform_mapping(
- pg_tbl, pte->sublevel + slot_idx, slot_base + slot_idx,
- host_addr, len, 0);
+ ret = gasket_perform_mapping(pg_tbl, pte->sublevel + slot_idx,
+ slot_base + slot_idx, host_addr,
+ len, 0);
if (ret) {
- gasket_page_table_unmap_nolock(
- pg_tbl, dev_addr, num_pages);
+ gasket_page_table_unmap_nolock(pg_tbl, dev_addr,
+ num_pages);
return ret;
}
@@ -1029,9 +1029,8 @@ static int gasket_map_extended_pages(
*
* The page table mutex is held for the entire operation.
*/
-int gasket_page_table_map(
- struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr,
- uint num_pages)
+int gasket_page_table_map(struct gasket_page_table *pg_tbl, ulong host_addr,
+ ulong dev_addr, uint num_pages)
{
int ret;
@@ -1041,11 +1040,11 @@ int gasket_page_table_map(
mutex_lock(&pg_tbl->mutex);
if (gasket_addr_is_simple(pg_tbl, dev_addr)) {
- ret = gasket_map_simple_pages(
- pg_tbl, host_addr, dev_addr, num_pages);
+ ret = gasket_map_simple_pages(pg_tbl, host_addr, dev_addr,
+ num_pages);
} else {
- ret = gasket_map_extended_pages(
- pg_tbl, host_addr, dev_addr, num_pages);
+ ret = gasket_map_extended_pages(pg_tbl, host_addr, dev_addr,
+ num_pages);
}
mutex_unlock(&pg_tbl->mutex);
@@ -1067,8 +1066,8 @@ EXPORT_SYMBOL(gasket_page_table_map);
*
* The page table mutex is held for the entire operation.
*/
-void gasket_page_table_unmap(
- struct gasket_page_table *pg_tbl, ulong dev_addr, uint num_pages)
+void gasket_page_table_unmap(struct gasket_page_table *pg_tbl, ulong dev_addr,
+ uint num_pages)
{
if (!num_pages)
return;
@@ -1081,12 +1080,15 @@ EXPORT_SYMBOL(gasket_page_table_unmap);
static void gasket_page_table_unmap_all_nolock(struct gasket_page_table *pg_tbl)
{
- gasket_unmap_simple_pages(
- pg_tbl, gasket_components_to_dev_address(pg_tbl, 1, 0, 0),
- pg_tbl->num_simple_entries);
- gasket_unmap_extended_pages(
- pg_tbl, gasket_components_to_dev_address(pg_tbl, 0, 0, 0),
- pg_tbl->num_extended_entries * GASKET_PAGES_PER_SUBTABLE);
+ gasket_unmap_simple_pages(pg_tbl,
+ gasket_components_to_dev_address(pg_tbl, 1, 0,
+ 0),
+ pg_tbl->num_simple_entries);
+ gasket_unmap_extended_pages(pg_tbl,
+ gasket_components_to_dev_address(pg_tbl, 0,
+ 0, 0),
+ pg_tbl->num_extended_entries *
+ GASKET_PAGES_PER_SUBTABLE);
}
/* See gasket_page_table.h for description. */
@@ -1189,8 +1191,8 @@ bool gasket_page_table_is_dev_addr_bad(
}
if (gasket_addr_is_simple(pg_tbl, dev_addr))
- return gasket_is_simple_dev_addr_bad(
- pg_tbl, dev_addr, num_pages);
+ return gasket_is_simple_dev_addr_bad(pg_tbl, dev_addr,
+ num_pages);
return gasket_is_extended_dev_addr_bad(pg_tbl, dev_addr, num_pages);
}
EXPORT_SYMBOL(gasket_page_table_is_dev_addr_bad);
diff --git a/drivers/staging/gasket/gasket_page_table.h b/drivers/staging/gasket/gasket_page_table.h
index 765588649365..00c06f050eb9 100644
--- a/drivers/staging/gasket/gasket_page_table.h
+++ b/drivers/staging/gasket/gasket_page_table.h
@@ -46,11 +46,10 @@ struct gasket_page_table;
*
* Returns 0 on success, a negative error code otherwise.
*/
-int gasket_page_table_init(
- struct gasket_page_table **ppg_tbl,
- const struct gasket_bar_data *bar_data,
- const struct gasket_page_table_config *page_table_config,
- struct device *device, struct pci_dev *pci_dev);
+int gasket_page_table_init(struct gasket_page_table **ppg_tbl,
+ const struct gasket_bar_data *bar_data,
+ const struct gasket_page_table_config *page_table_config,
+ struct device *device, struct pci_dev *pci_dev);
/*
* Deallocate and cleanup page table data.
@@ -77,8 +76,8 @@ void gasket_page_table_cleanup(struct gasket_page_table *page_table);
* Returns 0 if successful, or non-zero if the page table entries
* are not free.
*/
-int gasket_page_table_partition(
- struct gasket_page_table *page_table, uint num_simple_entries);
+int gasket_page_table_partition(struct gasket_page_table *page_table,
+ uint num_simple_entries);
/*
* Get and map [host] user space pages into device memory.
@@ -106,8 +105,8 @@ int gasket_page_table_map(struct gasket_page_table *page_table, ulong host_addr,
*
* Description: The inverse of gasket_map_pages. Unmaps pages from the device.
*/
-void gasket_page_table_unmap(
- struct gasket_page_table *page_table, ulong dev_addr, uint num_pages);
+void gasket_page_table_unmap(struct gasket_page_table *page_table,
+ ulong dev_addr, uint num_pages);
/*
* Unmap ALL host pages from device memory.
@@ -146,9 +145,9 @@ void gasket_page_table_garbage_collect(struct gasket_page_table *page_table);
* Returns 0 if successful, -1 for an error. The page pointer
* and offset are returned through the pointers, if successful.
*/
-int gasket_page_table_lookup_page(
- struct gasket_page_table *page_table, ulong dev_addr,
- struct page **page, ulong *poffset);
+int gasket_page_table_lookup_page(struct gasket_page_table *page_table,
+ ulong dev_addr, struct page **page,
+ ulong *poffset);
/*
* Checks validity for input addrs and size.
@@ -163,9 +162,9 @@ int gasket_page_table_lookup_page(
*
* Returns true if the mapping is bad, false otherwise.
*/
-bool gasket_page_table_are_addrs_bad(
- struct gasket_page_table *page_table, ulong host_addr, ulong dev_addr,
- ulong bytes);
+bool gasket_page_table_are_addrs_bad(struct gasket_page_table *page_table,
+ ulong host_addr, ulong dev_addr,
+ ulong bytes);
/*
* Checks validity for input dev addr and size.
@@ -179,8 +178,8 @@ bool gasket_page_table_are_addrs_bad(
*
* Returns true if the address is bad, false otherwise.
*/
-bool gasket_page_table_is_dev_addr_bad(
- struct gasket_page_table *page_table, ulong dev_addr, ulong bytes);
+bool gasket_page_table_is_dev_addr_bad(struct gasket_page_table *page_table,
+ ulong dev_addr, ulong bytes);
/*
* Gets maximum size for the given page table.
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 09/15] staging: gasket: sysfs: fix function param line continuation style
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
` (7 preceding siblings ...)
2018-07-31 20:24 ` [PATCH 08/15] staging: gasket: page table: " Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 10/15] staging: gasket: interrupt: " Todd Poynor
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
Fix multi-line alignment formatting to look like:
int ret = long_function_name(device, VARIABLE1, VARIABLE2,
VARIABLE3, VARIABLE4);
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/gasket_sysfs.c | 26 +++++++++++-----------
drivers/staging/gasket/gasket_sysfs.h | 32 +++++++++++++--------------
2 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/drivers/staging/gasket/gasket_sysfs.c b/drivers/staging/gasket/gasket_sysfs.c
index ef4eca02afa6..a4bfca43cd03 100644
--- a/drivers/staging/gasket/gasket_sysfs.c
+++ b/drivers/staging/gasket/gasket_sysfs.c
@@ -145,8 +145,8 @@ void gasket_sysfs_init(void)
}
}
-int gasket_sysfs_create_mapping(
- struct device *device, struct gasket_dev *gasket_dev)
+int gasket_sysfs_create_mapping(struct device *device,
+ struct gasket_dev *gasket_dev)
{
struct gasket_sysfs_mapping *mapping;
int map_idx = -1;
@@ -210,8 +210,8 @@ int gasket_sysfs_create_mapping(
return 0;
}
-int gasket_sysfs_create_entries(
- struct device *device, const struct gasket_sysfs_attribute *attrs)
+int gasket_sysfs_create_entries(struct device *device,
+ const struct gasket_sysfs_attribute *attrs)
{
int i;
int ret;
@@ -293,8 +293,8 @@ void gasket_sysfs_put_device_data(struct device *device, struct gasket_dev *dev)
}
EXPORT_SYMBOL(gasket_sysfs_put_device_data);
-struct gasket_sysfs_attribute *gasket_sysfs_get_attr(
- struct device *device, struct device_attribute *attr)
+struct gasket_sysfs_attribute *
+gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr)
{
int i;
int num_attrs;
@@ -317,8 +317,8 @@ struct gasket_sysfs_attribute *gasket_sysfs_get_attr(
}
EXPORT_SYMBOL(gasket_sysfs_get_attr);
-void gasket_sysfs_put_attr(
- struct device *device, struct gasket_sysfs_attribute *attr)
+void gasket_sysfs_put_attr(struct device *device,
+ struct gasket_sysfs_attribute *attr)
{
int i;
int num_attrs;
@@ -342,9 +342,9 @@ void gasket_sysfs_put_attr(
}
EXPORT_SYMBOL(gasket_sysfs_put_attr);
-ssize_t gasket_sysfs_register_store(
- struct device *device, struct device_attribute *attr, const char *buf,
- size_t count)
+ssize_t gasket_sysfs_register_store(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
ulong parsed_value = 0;
struct gasket_sysfs_mapping *mapping;
@@ -386,8 +386,8 @@ ssize_t gasket_sysfs_register_store(
gasket_attr->data.bar_address.offset);
if (gasket_attr->write_callback)
- gasket_attr->write_callback(
- gasket_dev, gasket_attr, parsed_value);
+ gasket_attr->write_callback(gasket_dev, gasket_attr,
+ parsed_value);
gasket_sysfs_put_attr(device, gasket_attr);
put_mapping(mapping);
diff --git a/drivers/staging/gasket/gasket_sysfs.h b/drivers/staging/gasket/gasket_sysfs.h
index e9f4fad80461..f32eaf89e056 100644
--- a/drivers/staging/gasket/gasket_sysfs.h
+++ b/drivers/staging/gasket/gasket_sysfs.h
@@ -68,9 +68,9 @@ struct gasket_sysfs_attribute {
* The callback should perform any logging necessary, as errors cannot
* be returned from the callback.
*/
- void (*write_callback)(
- struct gasket_dev *dev, struct gasket_sysfs_attribute *attr,
- ulong value);
+ void (*write_callback)(struct gasket_dev *dev,
+ struct gasket_sysfs_attribute *attr,
+ ulong value);
};
#define GASKET_SYSFS_RO(_name, _show_function, _attr_type) \
@@ -98,8 +98,8 @@ void gasket_sysfs_init(void);
* If this function is not called before gasket_sysfs_create_entries, a warning
* will be logged.
*/
-int gasket_sysfs_create_mapping(
- struct device *device, struct gasket_dev *gasket_dev);
+int gasket_sysfs_create_mapping(struct device *device,
+ struct gasket_dev *gasket_dev);
/*
* Creates bulk entries in sysfs.
@@ -111,8 +111,8 @@ int gasket_sysfs_create_mapping(
* gasket_sysfs_create_mapping had a legacy device, the entries will be created
* for it, as well.
*/
-int gasket_sysfs_create_entries(
- struct device *device, const struct gasket_sysfs_attribute *attrs);
+int gasket_sysfs_create_entries(struct device *device,
+ const struct gasket_sysfs_attribute *attrs);
/*
* Removes a device mapping from the global table.
@@ -141,8 +141,8 @@ struct gasket_dev *gasket_sysfs_get_device_data(struct device *device);
* @device: Kernel device structure.
* @dev: Gasket device descriptor (returned by gasket_sysfs_get_device_data).
*/
-void gasket_sysfs_put_device_data(
- struct device *device, struct gasket_dev *gasket_dev);
+void gasket_sysfs_put_device_data(struct device *device,
+ struct gasket_dev *gasket_dev);
/*
* Gasket-specific attribute lookup.
@@ -155,8 +155,8 @@ void gasket_sysfs_put_device_data(
* gasket_sysfs_get_device_data. While this reference is held, the underlying
* device sysfs information/structure will remain valid/will not be deleted.
*/
-struct gasket_sysfs_attribute *gasket_sysfs_get_attr(
- struct device *device, struct device_attribute *attr);
+struct gasket_sysfs_attribute *
+gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr);
/*
* Releases a references to internal data.
@@ -164,16 +164,16 @@ struct gasket_sysfs_attribute *gasket_sysfs_get_attr(
* @attr: Gasket sysfs attribute descriptor (returned by
* gasket_sysfs_get_attr).
*/
-void gasket_sysfs_put_attr(
- struct device *device, struct gasket_sysfs_attribute *attr);
+void gasket_sysfs_put_attr(struct device *device,
+ struct gasket_sysfs_attribute *attr);
/*
* Write to a register sysfs node.
* @buf: NULL-terminated data being written.
* @count: number of bytes in the "buf" argument.
*/
-ssize_t gasket_sysfs_register_store(
- struct device *device, struct device_attribute *attr, const char *buf,
- size_t count);
+ssize_t gasket_sysfs_register_store(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
#endif /* __GASKET_SYSFS_H__ */
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 10/15] staging: gasket: interrupt: fix function param line continuation style
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
` (8 preceding siblings ...)
2018-07-31 20:24 ` [PATCH 09/15] staging: gasket: sysfs: " Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 11/15] staging: gasket: TODO: remove entry for multi-line alignment style Todd Poynor
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
Fix multi-line alignment formatting to look like:
int ret = long_function_name(device, VARIABLE1, VARIABLE2,
VARIABLE3, VARIABLE4);
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/gasket_interrupt.c | 73 +++++++++++------------
drivers/staging/gasket/gasket_interrupt.h | 19 +++---
2 files changed, 43 insertions(+), 49 deletions(-)
diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c
index 3079b59b122b..09c3d0747af6 100644
--- a/drivers/staging/gasket/gasket_interrupt.c
+++ b/drivers/staging/gasket/gasket_interrupt.c
@@ -144,11 +144,10 @@ static void gasket_interrupt_setup(struct gasket_dev *gasket_dev)
}
mask = ~(0xFFFF << pack_shift);
- value = gasket_dev_read_64(
- gasket_dev,
- interrupt_data->interrupt_bar_index,
- interrupt_data->interrupts[i].reg) &
- mask;
+ value = gasket_dev_read_64(gasket_dev,
+ interrupt_data->interrupt_bar_index,
+ interrupt_data->interrupts[i].reg);
+ value &= mask;
value |= interrupt_data->interrupts[i].index
<< pack_shift;
}
@@ -187,8 +186,8 @@ static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int gasket_interrupt_msix_init(
- struct gasket_interrupt_data *interrupt_data)
+static int
+gasket_interrupt_msix_init(struct gasket_interrupt_data *interrupt_data)
{
int ret = 1;
int i;
@@ -210,10 +209,9 @@ static int gasket_interrupt_msix_init(
interrupt_data->msix_configured = 1;
for (i = 0; i < interrupt_data->num_interrupts; i++) {
- ret = request_irq(
- interrupt_data->msix_entries[i].vector,
- gasket_msix_interrupt_handler, 0, interrupt_data->name,
- interrupt_data);
+ ret = request_irq(interrupt_data->msix_entries[i].vector,
+ gasket_msix_interrupt_handler, 0,
+ interrupt_data->name, interrupt_data);
if (ret) {
dev_err(&interrupt_data->pci_dev->dev,
@@ -250,25 +248,23 @@ static void force_msix_interrupt_unmasking(struct gasket_dev *gasket_dev)
ulong location = APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE +
MSIX_MASK_BIT_OFFSET + i * MSIX_VECTOR_SIZE;
u32 mask =
- gasket_dev_read_32(
- gasket_dev,
- gasket_dev->interrupt_data->interrupt_bar_index,
- location);
+ gasket_dev_read_32(gasket_dev,
+ gasket_dev->interrupt_data->interrupt_bar_index,
+ location);
if (!(mask & 1))
continue;
/* Unmask the msix vector (clear 32 bits) */
- gasket_dev_write_32(
- gasket_dev, 0,
- gasket_dev->interrupt_data->interrupt_bar_index,
- location);
+ gasket_dev_write_32(gasket_dev, 0,
+ gasket_dev->interrupt_data->interrupt_bar_index,
+ location);
}
#undef MSIX_VECTOR_SIZE
#undef MSIX_MASK_BIT_OFFSET
#undef APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE
}
-static ssize_t interrupt_sysfs_show(
- struct device *device, struct device_attribute *attr, char *buf)
+static ssize_t interrupt_sysfs_show(struct device *device,
+ struct device_attribute *attr, char *buf)
{
int i, ret;
ssize_t written = 0, total_written = 0;
@@ -318,22 +314,22 @@ static ssize_t interrupt_sysfs_show(
}
static struct gasket_sysfs_attribute interrupt_sysfs_attrs[] = {
- GASKET_SYSFS_RO(
- interrupt_counts, interrupt_sysfs_show, ATTR_INTERRUPT_COUNTS),
+ GASKET_SYSFS_RO(interrupt_counts, interrupt_sysfs_show,
+ ATTR_INTERRUPT_COUNTS),
GASKET_END_OF_ATTR_ARRAY,
};
-int gasket_interrupt_init(
- struct gasket_dev *gasket_dev, const char *name, int type,
- const struct gasket_interrupt_desc *interrupts,
- int num_interrupts, int pack_width, int bar_index,
- const struct gasket_wire_interrupt_offsets *wire_int_offsets)
+int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name,
+ int type,
+ const struct gasket_interrupt_desc *interrupts,
+ int num_interrupts, int pack_width, int bar_index,
+ const struct gasket_wire_interrupt_offsets *wire_int_offsets)
{
int ret;
struct gasket_interrupt_data *interrupt_data;
- interrupt_data = kzalloc(
- sizeof(struct gasket_interrupt_data), GFP_KERNEL);
+ interrupt_data = kzalloc(sizeof(struct gasket_interrupt_data),
+ GFP_KERNEL);
if (!interrupt_data)
return -ENOMEM;
gasket_dev->interrupt_data = interrupt_data;
@@ -402,14 +398,14 @@ int gasket_interrupt_init(
}
gasket_interrupt_setup(gasket_dev);
- gasket_sysfs_create_entries(
- gasket_dev->dev_info.device, interrupt_sysfs_attrs);
+ gasket_sysfs_create_entries(gasket_dev->dev_info.device,
+ interrupt_sysfs_attrs);
return 0;
}
-static void gasket_interrupt_msix_cleanup(
- struct gasket_interrupt_data *interrupt_data)
+static void
+gasket_interrupt_msix_cleanup(struct gasket_interrupt_data *interrupt_data)
{
int i;
@@ -528,9 +524,8 @@ int gasket_interrupt_system_status(struct gasket_dev *gasket_dev)
return GASKET_STATUS_ALIVE;
}
-int gasket_interrupt_set_eventfd(
- struct gasket_interrupt_data *interrupt_data, int interrupt,
- int event_fd)
+int gasket_interrupt_set_eventfd(struct gasket_interrupt_data *interrupt_data,
+ int interrupt, int event_fd)
{
struct eventfd_ctx *ctx = eventfd_ctx_fdget(event_fd);
@@ -544,8 +539,8 @@ int gasket_interrupt_set_eventfd(
return 0;
}
-int gasket_interrupt_clear_eventfd(
- struct gasket_interrupt_data *interrupt_data, int interrupt)
+int gasket_interrupt_clear_eventfd(struct gasket_interrupt_data *interrupt_data,
+ int interrupt)
{
if (interrupt < 0 || interrupt >= interrupt_data->num_interrupts)
return -EINVAL;
diff --git a/drivers/staging/gasket/gasket_interrupt.h b/drivers/staging/gasket/gasket_interrupt.h
index 805fee64569f..835af439e96a 100644
--- a/drivers/staging/gasket/gasket_interrupt.h
+++ b/drivers/staging/gasket/gasket_interrupt.h
@@ -43,11 +43,11 @@ struct gasket_interrupt_data;
* are not possible to set up, but is otherwise OK; that device will report
* status LAMED.)
*/
-int gasket_interrupt_init(
- struct gasket_dev *gasket_dev, const char *name, int type,
- const struct gasket_interrupt_desc *interrupts,
- int num_interrupts, int pack_width, int bar_index,
- const struct gasket_wire_interrupt_offsets *wire_int_offsets);
+int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name,
+ int type,
+ const struct gasket_interrupt_desc *interrupts,
+ int num_interrupts, int pack_width, int bar_index,
+ const struct gasket_wire_interrupt_offsets *wire_int_offsets);
/*
* Clean up a device's interrupt structure.
@@ -87,9 +87,8 @@ int gasket_interrupt_reset_counts(struct gasket_dev *gasket_dev);
*
* Returns 0 on success, a negative error code otherwise.
*/
-int gasket_interrupt_set_eventfd(
- struct gasket_interrupt_data *interrupt_data, int interrupt,
- int event_fd);
+int gasket_interrupt_set_eventfd(struct gasket_interrupt_data *interrupt_data,
+ int interrupt, int event_fd);
/*
* Removes an interrupt-eventfd association.
@@ -98,8 +97,8 @@ int gasket_interrupt_set_eventfd(
*
* Removes any eventfd associated with the specified interrupt, if any.
*/
-int gasket_interrupt_clear_eventfd(
- struct gasket_interrupt_data *interrupt_data, int interrupt);
+int gasket_interrupt_clear_eventfd(struct gasket_interrupt_data *interrupt_data,
+ int interrupt);
/*
* The below functions exist for backwards compatibility.
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 11/15] staging: gasket: TODO: remove entry for multi-line alignment style
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
` (9 preceding siblings ...)
2018-07-31 20:24 ` [PATCH 10/15] staging: gasket: interrupt: " Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 12/15] staging: gasket: apex: move driver-private defines out of apex.h Todd Poynor
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
Multi-line alignment formatting issues fixed, remove the TODO entry for
this.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/TODO | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/staging/gasket/TODO b/drivers/staging/gasket/TODO
index 6aa2a7f6bc4b..6ff8e01b04cc 100644
--- a/drivers/staging/gasket/TODO
+++ b/drivers/staging/gasket/TODO
@@ -4,9 +4,6 @@ staging directory.
- Use misc interface instead of major number for driver version description.
- Add descriptions of module_param's
- apex_get_status() should actually check status.
-- Fix multi-line alignment formatting to look like:
- int ret = long_function_name(device, VARIABLE1, VARIABLE2,
- VARIABLE3, VARIABLE4);
- "drivers" should never be dealing with "raw" sysfs calls or mess around with
kobjects at all. The driver core should handle all of this for you
automaically. There should not be a need for raw attribute macros.
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 12/15] staging: gasket: apex: move driver-private defines out of apex.h
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
` (10 preceding siblings ...)
2018-07-31 20:24 ` [PATCH 11/15] staging: gasket: TODO: remove entry for multi-line alignment style Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 13/15] staging: gasket: core: use bool type for ns_capable result Todd Poynor
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
apex.h is supposed to contain kernel-userspace interface definitions,
but has a number of defines that are only used by apex_driver.c or are
not used at all. Move driver implementation defines not shared with
userspace to the driver source. Remove unused defines.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/apex.h | 62 +---------------------------
drivers/staging/gasket/apex_driver.c | 29 +++++++++++++
2 files changed, 31 insertions(+), 60 deletions(-)
diff --git a/drivers/staging/gasket/apex.h b/drivers/staging/gasket/apex.h
index d89cc2387b7d..3bbceffff5e4 100644
--- a/drivers/staging/gasket/apex.h
+++ b/drivers/staging/gasket/apex.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Apex kernel-userspace interface definition(s).
+ * Apex kernel-userspace interface definitions.
*
* Copyright (C) 2018 Google, Inc.
*/
@@ -8,66 +8,8 @@
#define __APEX_H__
#include <linux/ioctl.h>
-#include <linux/bitops.h>
-#include "gasket.h"
-
-/* Structural definitions/macros. */
-/* The number of PCI BARs. */
-#define APEX_NUM_BARS 3
-
-/* Size of a memory page in bytes, and the related number of bits to shift. */
-#define APEX_PAGE_SHIFT 12
-#define APEX_PAGE_SIZE BIT(APEX_PAGE_SHIFT)
-
-#define APEX_EXTENDED_SHIFT 63 /* Extended address bit position. */
-
-/*
- * Addresses are 2^3=8 bytes each. Page in second level page table holds
- * APEX_PAGE_SIZE/8 addresses.
- */
-#define APEX_ADDR_SHIFT 3
-#define APEX_LEVEL_SHIFT (APEX_PAGE_SHIFT - APEX_ADDR_SHIFT)
-#define APEX_LEVEL_SIZE BIT(APEX_LEVEL_SHIFT)
-
-#define APEX_PAGE_TABLE_MAX 65536
-#define APEX_SIMPLE_PAGE_MAX APEX_PAGE_TABLE_MAX
-#define APEX_EXTENDED_PAGE_MAX (APEX_PAGE_TABLE_MAX << APEX_LEVEL_SHIFT)
-
-/* Check reset 120 times */
-#define APEX_RESET_RETRY 120
-/* Wait 100 ms between checks. Total 12 sec wait maximum. */
-#define APEX_RESET_DELAY 100
-
-#define APEX_CHIP_INIT_DONE 2
-#define APEX_RESET_ACCEPTED 0
-
-enum apex_reset_types {
- APEX_CHIP_REINIT_RESET = 3,
-};
-
-/* Interrupt defines */
-/* Gasket device interrupts enums must be dense (i.e., no empty slots). */
-enum apex_interrupt {
- APEX_INTERRUPT_INSTR_QUEUE = 0,
- APEX_INTERRUPT_INPUT_ACTV_QUEUE = 1,
- APEX_INTERRUPT_PARAM_QUEUE = 2,
- APEX_INTERRUPT_OUTPUT_ACTV_QUEUE = 3,
- APEX_INTERRUPT_SC_HOST_0 = 4,
- APEX_INTERRUPT_SC_HOST_1 = 5,
- APEX_INTERRUPT_SC_HOST_2 = 6,
- APEX_INTERRUPT_SC_HOST_3 = 7,
- APEX_INTERRUPT_TOP_LEVEL_0 = 8,
- APEX_INTERRUPT_TOP_LEVEL_1 = 9,
- APEX_INTERRUPT_TOP_LEVEL_2 = 10,
- APEX_INTERRUPT_TOP_LEVEL_3 = 11,
- APEX_INTERRUPT_FATAL_ERR = 12,
- APEX_INTERRUPT_COUNT = 13,
-};
-
-/*
- * Clock Gating ioctl.
- */
+/* Clock Gating ioctl. */
struct apex_gate_clock_ioctl {
/* Enter or leave clock gated state. */
u64 enable;
diff --git a/drivers/staging/gasket/apex_driver.c b/drivers/staging/gasket/apex_driver.c
index c0d3922e1d7c..dfbff47b4608 100644
--- a/drivers/staging/gasket/apex_driver.c
+++ b/drivers/staging/gasket/apex_driver.c
@@ -54,6 +54,17 @@
*/
#define APEX_PAGE_TABLE_TOTAL_ENTRIES 8192
+#define APEX_EXTENDED_SHIFT 63 /* Extended address bit position. */
+
+enum apex_reset_types {
+ APEX_CHIP_REINIT_RESET = 3,
+};
+
+/* Check reset 120 times */
+#define APEX_RESET_RETRY 120
+/* Wait 100 ms between checks. Total 12 sec wait maximum. */
+#define APEX_RESET_DELAY 100
+
/* Enumeration of the supported sysfs entries. */
enum sysfs_attribute_type {
ATTR_KERNEL_HIB_PAGE_TABLE_SIZE,
@@ -133,6 +144,24 @@ static const struct gasket_mappable_region mappable_regions[NUM_REGIONS] = {
static const struct gasket_mappable_region cm_mappable_regions[1] = { { 0x0,
APEX_CH_MEM_BYTES } };
+/* Gasket device interrupts enums must be dense (i.e., no empty slots). */
+enum apex_interrupt {
+ APEX_INTERRUPT_INSTR_QUEUE = 0,
+ APEX_INTERRUPT_INPUT_ACTV_QUEUE = 1,
+ APEX_INTERRUPT_PARAM_QUEUE = 2,
+ APEX_INTERRUPT_OUTPUT_ACTV_QUEUE = 3,
+ APEX_INTERRUPT_SC_HOST_0 = 4,
+ APEX_INTERRUPT_SC_HOST_1 = 5,
+ APEX_INTERRUPT_SC_HOST_2 = 6,
+ APEX_INTERRUPT_SC_HOST_3 = 7,
+ APEX_INTERRUPT_TOP_LEVEL_0 = 8,
+ APEX_INTERRUPT_TOP_LEVEL_1 = 9,
+ APEX_INTERRUPT_TOP_LEVEL_2 = 10,
+ APEX_INTERRUPT_TOP_LEVEL_3 = 11,
+ APEX_INTERRUPT_FATAL_ERR = 12,
+ APEX_INTERRUPT_COUNT = 13,
+};
+
/* Interrupt descriptors for Apex */
static struct gasket_interrupt_desc apex_interrupts[] = {
{
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 13/15] staging: gasket: core: use bool type for ns_capable result
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
` (11 preceding siblings ...)
2018-07-31 20:24 ` [PATCH 12/15] staging: gasket: apex: move driver-private defines out of apex.h Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 14/15] Revert "staging: gasket: page table: hold references to device and pci_dev" Todd Poynor
2018-07-31 20:24 ` [PATCH 15/15] staging: gasket: page table: fix header file include guard symbol Todd Poynor
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
When gasket core was converted from using capable() to use ns_capable()
instead, the type of the variable holding the result should have been
converted from int to bool.
Reported-by: Dmitry Torokhov <dtor@chromium.org>
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/gasket_core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c
index 44344528cd88..f76f4a0ecbac 100644
--- a/drivers/staging/gasket/gasket_core.c
+++ b/drivers/staging/gasket/gasket_core.c
@@ -1191,7 +1191,7 @@ static int gasket_open(struct inode *inode, struct file *filp)
struct gasket_cdev_info *dev_info =
container_of(inode->i_cdev, struct gasket_cdev_info, cdev);
struct pid_namespace *pid_ns = task_active_pid_ns(current);
- int is_root = ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN);
+ bool is_root = ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN);
gasket_dev = dev_info->gasket_dev_ptr;
driver_desc = gasket_dev->internal_desc->driver_desc;
@@ -1270,7 +1270,7 @@ static int gasket_release(struct inode *inode, struct file *file)
struct gasket_cdev_info *dev_info =
container_of(inode->i_cdev, struct gasket_cdev_info, cdev);
struct pid_namespace *pid_ns = task_active_pid_ns(current);
- int is_root = ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN);
+ bool is_root = ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN);
gasket_dev = dev_info->gasket_dev_ptr;
driver_desc = gasket_dev->internal_desc->driver_desc;
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 14/15] Revert "staging: gasket: page table: hold references to device and pci_dev"
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
` (12 preceding siblings ...)
2018-07-31 20:24 ` [PATCH 13/15] staging: gasket: core: use bool type for ns_capable result Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
2018-07-31 20:24 ` [PATCH 15/15] staging: gasket: page table: fix header file include guard symbol Todd Poynor
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
gasket_free_dev() is called only from driver PCI probe and remove
function. It is guaranteed that that pci_dev structure is not going
anywhere during that time; there is no need to take this additional
reference.
This reverts commit dd9d1502feea3c23d412f289aad79e1d4e86d45d.
Reported-by: Dmitry Torokhov <dtor@chromium.org>
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/gasket_page_table.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c
index 13e1d0952a47..ed6ab3c5f038 100644
--- a/drivers/staging/gasket/gasket_page_table.c
+++ b/drivers/staging/gasket/gasket_page_table.c
@@ -280,7 +280,7 @@ int gasket_page_table_init(struct gasket_page_table **ppg_tbl,
pg_tbl->extended_offset_reg =
(u64 __iomem *)&bar_data->virt_base[page_table_config->extended_reg];
pg_tbl->device = get_device(device);
- pg_tbl->pci_dev = pci_dev_get(pci_dev);
+ pg_tbl->pci_dev = pci_dev;
dev_dbg(device, "Page table initialized successfully\n");
@@ -378,7 +378,6 @@ void gasket_page_table_cleanup(struct gasket_page_table *pg_tbl)
pg_tbl->entries = NULL;
put_device(pg_tbl->device);
- pci_dev_put(pg_tbl->pci_dev);
kfree(pg_tbl);
}
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 15/15] staging: gasket: page table: fix header file include guard symbol
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
` (13 preceding siblings ...)
2018-07-31 20:24 ` [PATCH 14/15] Revert "staging: gasket: page table: hold references to device and pci_dev" Todd Poynor
@ 2018-07-31 20:24 ` Todd Poynor
14 siblings, 0 replies; 16+ messages in thread
From: Todd Poynor @ 2018-07-31 20:24 UTC (permalink / raw)
To: Rob Springer, John Joseph, Ben Chan, Greg Kroah-Hartman
Cc: Dmitry Torokhov, devel, linux-kernel, Todd Poynor
From: Todd Poynor <toddpoynor@google.com>
The include guard symbol for gasket_page_table.h is out-of-date.
Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
drivers/staging/gasket/gasket_page_table.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/gasket/gasket_page_table.h b/drivers/staging/gasket/gasket_page_table.h
index 00c06f050eb9..7b01b73ea3e7 100644
--- a/drivers/staging/gasket/gasket_page_table.h
+++ b/drivers/staging/gasket/gasket_page_table.h
@@ -9,8 +9,8 @@
* Copyright (C) 2018 Google, Inc.
*/
-#ifndef __GASKET_ADDR_TRNSL_H__
-#define __GASKET_ADDR_TRNSL_H__
+#ifndef __GASKET_PAGE_TABLE_H__
+#define __GASKET_PAGE_TABLE_H__
#include <linux/pci.h>
#include <linux/types.h>
@@ -246,4 +246,4 @@ void gasket_free_coherent_memory_all(struct gasket_dev *gasket_dev,
int gasket_set_user_virt(struct gasket_dev *gasket_dev, uint64_t size,
dma_addr_t dma_address, ulong vma);
-#endif
+#endif /* __GASKET_PAGE_TABLE_H__ */
--
2.18.0.345.g5c9ce644c3-goog
^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2018-07-31 20:26 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-31 20:24 [PATCH 00/15] staging: gasket: cleanups continue Todd Poynor
2018-07-31 20:24 ` [PATCH 01/15] staging: gasket: core: remove static function forward declarations Todd Poynor
2018-07-31 20:24 ` [PATCH 02/15] staging: gasket: ioctl: " Todd Poynor
2018-07-31 20:24 ` [PATCH 03/15] staging: gasket: interrupt: " Todd Poynor
2018-07-31 20:24 ` [PATCH 04/15] staging: gasket: pg tbl: " Todd Poynor
2018-07-31 20:24 ` [PATCH 05/15] staging: gasket: TODO: remove entry for static function declarations Todd Poynor
2018-07-31 20:24 ` [PATCH 06/15] staging: gasket: core: fix function param line continuation style Todd Poynor
2018-07-31 20:24 ` [PATCH 07/15] staging: gasket: ioctl: " Todd Poynor
2018-07-31 20:24 ` [PATCH 08/15] staging: gasket: page table: " Todd Poynor
2018-07-31 20:24 ` [PATCH 09/15] staging: gasket: sysfs: " Todd Poynor
2018-07-31 20:24 ` [PATCH 10/15] staging: gasket: interrupt: " Todd Poynor
2018-07-31 20:24 ` [PATCH 11/15] staging: gasket: TODO: remove entry for multi-line alignment style Todd Poynor
2018-07-31 20:24 ` [PATCH 12/15] staging: gasket: apex: move driver-private defines out of apex.h Todd Poynor
2018-07-31 20:24 ` [PATCH 13/15] staging: gasket: core: use bool type for ns_capable result Todd Poynor
2018-07-31 20:24 ` [PATCH 14/15] Revert "staging: gasket: page table: hold references to device and pci_dev" Todd Poynor
2018-07-31 20:24 ` [PATCH 15/15] staging: gasket: page table: fix header file include guard symbol Todd Poynor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).