// SPDX-License-Identifier: GPL-2.0
/*
 * Gasket generic driver framework. This file contains the implementation
 * for the Gasket generic driver framework - the functionality that is common
 * across Gasket devices.
 *
 * Copyright (C) 2018 Google, Inc.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include "gasket_core.h"

#include "gasket_interrupt.h"
#include "gasket_ioctl.h"
#include "gasket_page_table.h"
#include "gasket_sysfs.h"

#include <linux/capability.h>
#include <linux/compiler.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/pid_namespace.h>
#include <linux/platform_device.h>
#include <linux/printk.h>
#include <linux/sched.h>

#ifdef GASKET_KERNEL_TRACE_SUPPORT
#define CREATE_TRACE_POINTS
#include <trace/events/gasket_mmap.h>
#else
#define trace_gasket_mmap_exit(x)
#define trace_gasket_mmap_entry(x, ...)
#endif

/*
 * "Private" members of gasket_driver_desc.
 *
 * Contains internal per-device type tracking data, i.e., data not appropriate
 * as part of the public interface for the generic framework.
 */
struct gasket_internal_desc {
	/* Device-specific-driver-provided configuration information. */
	const struct gasket_driver_desc *driver_desc;

	/* Protects access to per-driver data (i.e. this structure). */
	struct mutex mutex;

	/* Kernel-internal device class. */
	struct class *class;

	/* Instantiated / present devices of this type. */
	struct gasket_dev *devs[GASKET_DEV_MAX];
};

/* do_map_region() needs be able to return more than just true/false. */
enum do_map_region_status {
	/* The region was successfully mapped. */
	DO_MAP_REGION_SUCCESS,

	/* Attempted to map region and failed. */
	DO_MAP_REGION_FAILURE,

	/* The requested region to map was not part of a mappable region. */
	DO_MAP_REGION_INVALID,
};

/* Global data definitions. */
/* Mutex - only for framework-wide data. Other data should be protected by
 * finer-grained locks.
 */
static DEFINE_MUTEX(g_mutex);

/* List of all registered device descriptions & their supporting data. */
static struct gasket_internal_desc g_descs[GASKET_FRAMEWORK_DESC_MAX];

/* Mapping of statuses to human-readable strings. Must end with {0,NULL}. */
static const struct gasket_num_name gasket_status_name_table[] = {
	{ GASKET_STATUS_DEAD, "DEAD" },
	{ GASKET_STATUS_ALIVE, "ALIVE" },
	{ GASKET_STATUS_LAMED, "LAMED" },
	{ GASKET_STATUS_DRIVER_EXIT, "DRIVER_EXITING" },
	{ 0, NULL },
};

/* Enumeration of the automatic Gasket framework sysfs nodes. */
enum gasket_sysfs_attribute_type {
	ATTR_BAR_OFFSETS,
	ATTR_BAR_SIZES,
	ATTR_DRIVER_VERSION,
	ATTR_FRAMEWORK_VERSION,
	ATTR_DEVICE_TYPE,
	ATTR_HARDWARE_REVISION,
	ATTR_PCI_ADDRESS,
	ATTR_STATUS,
	ATTR_IS_DEVICE_OWNED,
	ATTR_DEVICE_OWNER,
	ATTR_WRITE_OPEN_COUNT,
	ATTR_RESET_COUNT,
	ATTR_USER_MEM_RANGES
};

/* Perform a standard Gasket callback. */
static inline int
check_and_invoke_callback(struct gasket_dev *gasket_dev,
			  int (*cb_function)(struct gasket_dev *))
{
	int ret = 0;

	if (cb_function) {
		mutex_lock(&gasket_dev->mutex);
		ret = cb_function(gasket_dev);
		mutex_unlock(&gasket_dev->mutex);
	}
	return ret;
}

/* 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 *))
{
	int ret = 0;

	if (cb_function)
		ret = cb_function(gasket_dev);
	return ret;
}

/*
 * Return nonzero if the gasket_cdev_info is owned by the current thread group
 * ID.
 */
static int gasket_owned_by_current_tgid(struct gasket_cdev_info *info)
{
	return (info->ownership.is_owned &&
		(info->ownership.owner == current->tgid));
}

/*
 * 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;

	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;
}

/*
 * Allocate and initialize a Gasket device structure, add the device to the
 * device list.
 *
 * 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)
{
	int dev_idx;
	const struct gasket_driver_desc *driver_desc =
		internal_desc->driver_desc;
	struct gasket_dev *gasket_dev;
	struct gasket_cdev_info *dev_info;
	const char *parent_name = dev_name(parent);

	pr_debug("Allocating a Gasket device, parent %s.\n", parent_name);

	*pdev = NULL;

	dev_idx = gasket_find_dev_slot(internal_desc, parent_name);
	if (dev_idx < 0)
		return dev_idx;

	gasket_dev = *pdev = kzalloc(sizeof(*gasket_dev), GFP_KERNEL);
	if (!gasket_dev) {
		pr_err("no memory for device, parent %s\n", parent_name);
		return -ENOMEM;
	}
	internal_desc->devs[dev_idx] = gasket_dev;

	mutex_init(&gasket_dev->mutex);

	gasket_dev->internal_desc = internal_desc;
	gasket_dev->dev_idx = dev_idx;
	snprintf(gasket_dev->kobj_name, GASKET_NAME_MAX, "%s", parent_name);
	gasket_dev->dev = get_device(parent);
	gasket_dev->dma_dev = get_device(parent);
	/* gasket_bar_data is uninitialized. */
	gasket_dev->num_page_tables = driver_desc->num_page_tables;
	/* max_page_table_size and *page table are uninit'ed */
	/* interrupt_data is not initialized. */
	/* status is 0, or GASKET_STATUS_DEAD */

	dev_info = &gasket_dev->dev_info;
	snprintf(dev_info->name, GASKET_NAME_MAX, "%s_%u", driver_desc->name,
		 gasket_dev->dev_idx);
	dev_info->devt =
		MKDEV(driver_desc->major, driver_desc->minor +
		      gasket_dev->dev_idx);
	dev_info->device =
		device_create(internal_desc->class, parent, dev_info->devt,
			      gasket_dev, dev_info->name);

	/* cdev has not yet been added; cdev_added is 0 */
	dev_info->gasket_dev_ptr = gasket_dev;
	/* ownership is all 0, indicating no owner or opens. */

	return 0;
}

/* Free a Gasket device. */
static void gasket_free_dev(struct gasket_dev *gasket_dev)
{
	struct gasket_internal_desc *internal_desc = gasket_dev->internal_desc;

	mutex_lock(&internal_desc->mutex);
	internal_desc->devs[gasket_dev->dev_idx] = NULL;
	mutex_unlock(&internal_desc->mutex);
	put_device(gasket_dev->dev);
	put_device(gasket_dev->dma_dev);
	kfree(gasket_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 (driver_desc->bar_descriptions[bar_num].type != PCI_BAR) {
		/* not PCI: skip this entry */
		return 0;
	}
	/*
	 * pci_resource_start and pci_resource_len return a "resource_size_t",
	 * which is safely castable to ulong (which itself is the arg to
	 * request_mem_region).
	 */
	gasket_dev->bar_data[bar_num].phys_base =
		(ulong)pci_resource_start(gasket_dev->pci_dev, bar_num);
	if (!gasket_dev->bar_data[bar_num].phys_base) {
		dev_err(gasket_dev->dev, "Cannot get BAR%u base address\n",
			bar_num);
		return -EINVAL;
	}

	gasket_dev->bar_data[bar_num].length_bytes =
		(ulong)pci_resource_len(gasket_dev->pci_dev, bar_num);
	if (gasket_dev->bar_data[bar_num].length_bytes < desc_bytes) {
		dev_err(gasket_dev->dev,
			"PCI BAR %u space is too small: %lu; expected >= %lu\n",
			bar_num, gasket_dev->bar_data[bar_num].length_bytes,
			desc_bytes);
		return -ENOMEM;
	}

	if (!request_mem_region(gasket_dev->bar_data[bar_num].phys_base,
				gasket_dev->bar_data[bar_num].length_bytes,
				gasket_dev->dev_info.name)) {
		dev_err(gasket_dev->dev,
			"Cannot get BAR %d memory region %p\n",
			bar_num, &gasket_dev->pci_dev->resource[bar_num]);
		return -EINVAL;
	}

	gasket_dev->bar_data[bar_num].virt_base =
		ioremap_nocache(gasket_dev->bar_data[bar_num].phys_base,
				gasket_dev->bar_data[bar_num].length_bytes);
	if (!gasket_dev->bar_data[bar_num].virt_base) {
		dev_err(gasket_dev->dev,
			"Cannot remap BAR %d memory region %p\n",
			bar_num, &gasket_dev->pci_dev->resource[bar_num]);
		ret = -ENOMEM;
		goto fail;
	}

	dma_set_mask(&gasket_dev->pci_dev->dev, DMA_BIT_MASK(64));
	dma_set_coherent_mask(&gasket_dev->pci_dev->dev, DMA_BIT_MASK(64));

	return 0;

fail:
	iounmap(gasket_dev->bar_data[bar_num].virt_base);
	release_mem_region(gasket_dev->bar_data[bar_num].phys_base,
			   gasket_dev->bar_data[bar_num].length_bytes);
	return ret;
}

/*
 * Releases PCI BAR mapping.
 *
 * A zero-sized or not-mapped BAR will not be unmapped, but is not an error.
 */
static void gasket_unmap_pci_bar(struct gasket_dev *dev, int bar_num)
{
	ulong base, bytes;
	struct gasket_internal_desc *internal_desc = dev->internal_desc;
	const struct gasket_driver_desc *driver_desc =
		internal_desc->driver_desc;

	if (driver_desc->bar_descriptions[bar_num].size == 0 ||
	    !dev->bar_data[bar_num].virt_base)
		return;

	if (driver_desc->bar_descriptions[bar_num].type != PCI_BAR)
		return;

	iounmap(dev->bar_data[bar_num].virt_base);
	dev->bar_data[bar_num].virt_base = NULL;

	base = pci_resource_start(dev->pci_dev, bar_num);
	if (!base) {
		dev_err(dev->dev, "cannot get PCI BAR%u base address\n",
			bar_num);
		return;
	}

	bytes = pci_resource_len(dev->pci_dev, bar_num);
	release_mem_region(base, bytes);
}

/*
 * Setup PCI memory mapping for the specified 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;

	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);

	return -ENOMEM;
}

/* Unmaps memory 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);
}

/* 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;

	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;
	}

	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) {
		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;
		}
	}

	return GASKET_STATUS_ALIVE;
}

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];

	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 total_written;
}

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;
	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;
	}

	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 = gasket_dev->internal_desc->driver_desc;

	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;
	}

	gasket_sysfs_put_attr(device, gasket_attr);
	gasket_sysfs_put_device_data(device, gasket_dev);
	return ret;
}

/* 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
};

/* 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;
}

/* Disable device operations. */
void gasket_disable_device(struct gasket_dev *gasket_dev)
{
	const struct gasket_driver_desc *driver_desc =
		gasket_dev->internal_desc->driver_desc;
	int i;

	dev_dbg(gasket_dev->dev, "disabling device\n");
	/* 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;

	gasket_interrupt_cleanup(gasket_dev);

	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]);
		}
	}
}
EXPORT_SYMBOL(gasket_disable_device);

/*
 * Registered driver descriptor lookup for PCI devices.
 *
 * 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_pci_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];
	}

	return NULL;
}

/*
 * Registered driver descriptor lookup for platform devices.
 * Caller must hold g_mutex.
 */
static struct gasket_internal_desc *
lookup_platform_internal_desc(struct platform_device *pdev)
{
	int i;

	__must_hold(&g_mutex);
	for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
		if (g_descs[i].driver_desc &&
		    strcmp(g_descs[i].driver_desc->name, pdev->name) == 0)
			return &g_descs[i];
	}

	return NULL;
}

/*
 * Verifies that the user has permissions to perform the requested mapping and
 * 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)
{
	int requested_permissions;
	/* Always allow sysadmin to access. */
	if (capable(CAP_SYS_ADMIN))
		return true;

	/* Never allow non-sysadmins to access to a dead device. */
	if (gasket_dev->status != GASKET_STATUS_ALIVE) {
		dev_dbg(gasket_dev->dev, "Device is dead.\n");
		return false;
	}

	/* Make sure that no wrong flags are set. */
	requested_permissions =
		(vma->vm_flags & (VM_WRITE | VM_READ | VM_EXEC));
	if (requested_permissions & ~(bar_permissions)) {
		dev_dbg(gasket_dev->dev,
			"Attempting to map a region with requested permissions "
			"0x%x, but region has permissions 0x%x.\n",
			requested_permissions, bar_permissions);
		return false;
	}

	/* Do not allow a non-owner to write. */
	if ((vma->vm_flags & VM_WRITE) &&
	    !gasket_owned_by_current_tgid(&gasket_dev->dev_info)) {
		dev_dbg(gasket_dev->dev,
			"Attempting to mmap a region for write without owning "
			"device.\n");
		return false;
	}

	return true;
}

/*
 * 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)
{
	struct gasket_coherent_buffer_desc coh_buff_desc =
		driver_desc->coherent_buffer_description;

	if (coh_buff_desc.permissions != GASKET_NOMAP) {
		if ((address >= coh_buff_desc.base) &&
		    (address < coh_buff_desc.base + coh_buff_desc.size)) {
			return true;
		}
	}
	return false;
}

static int gasket_get_bar_index(const struct gasket_dev *gasket_dev,
				ulong phys_addr)
{
	int i;
	const struct gasket_driver_desc *driver_desc;

	driver_desc = gasket_dev->internal_desc->driver_desc;
	for (i = 0; i < GASKET_NUM_BARS; ++i) {
		struct gasket_bar_desc bar_desc =
			driver_desc->bar_descriptions[i];

		if (bar_desc.permissions != GASKET_NOMAP) {
			if (phys_addr >= bar_desc.base &&
			    phys_addr < (bar_desc.base + bar_desc.size)) {
				return i;
			}
		}
	}
	/* If we haven't found the address by now, it is invalid. */
	return -EINVAL;
}

/*
 * Sets the actual bounds to map, given the device's mappable region.
 *
 * Given the device's mappable region, along with the user-requested mapping
 * start offset and length of the user region, determine how much of this
 * mappable region can be mapped into the user's region (start/end offsets),
 * and the physical offset (phys_offset) into the BAR where the mapping should
 * begin (either the VMA's or region lower bound).
 *
 * In other words, this calculates the overlap between the VMA
 * (bar_offset, requested_length) and the given gasket_mappable_region.
 *
 * 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)
{
	ulong range_start = region->start;
	ulong range_length = region->length_bytes;
	ulong range_end = range_start + range_length;

	*virt_offset = 0;
	if (bar_offset + requested_length < range_start) {
		/*
		 * If the requested region is completely below the range,
		 * there is nothing to map.
		 */
		return false;
	} else if (bar_offset <= range_start) {
		/* If the bar offset is below this range's start
		 * but the requested length continues into it:
		 * 1) Only map starting from the beginning of this
		 *      range's phys. offset, so we don't map unmappable
		 *	memory.
		 * 2) The length of the virtual memory to not map is the
		 *	delta between the bar offset and the
		 *	mappable start (and since the mappable start is
		 *	bigger, start - req.)
		 * 3) The map length is the minimum of the mappable
		 *	requested length (requested_length - virt_offset)
		 *	and the actual mappable length of the range.
		 */
		mappable_region->start = range_start;
		*virt_offset = range_start - bar_offset;
		mappable_region->length_bytes =
			min(requested_length - *virt_offset, range_length);
		return true;
	} else if (bar_offset > range_start &&
		   bar_offset < range_end) {
		/*
		 * If the bar offset is within this range:
		 * 1) Map starting from the bar offset.
		 * 2) Because there is no forbidden memory between the
		 *	bar offset and the range start,
		 *	virt_offset is 0.
		 * 3) The map length is the minimum of the requested
		 *	length and the remaining length in the buffer
		 *	(range_end - bar_offset)
		 */
		mappable_region->start = bar_offset;
		*virt_offset = 0;
		mappable_region->length_bytes =
			min(requested_length, range_end - bar_offset);
		return true;
	}

	/*
	 * If the requested [start] offset is above range_end,
	 * there's nothing to map.
	 */
	return false;
}

/*
 * 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;

	if (map_region->length_bytes == 0)
		return 0;

	ret = gasket_mm_vma_bar_offset(gasket_dev, vma, &bar_offset);
	if (ret)
		return ret;

	if (!gasket_mm_get_mapping_addrs(map_region, bar_offset,
					 vma->vm_end - vma->vm_start,
					 &mappable_region, &virt_offset))
		return 1;

	/*
	 * The length passed to zap_vma_ptes MUST BE A MULTIPLE OF
	 * PAGE_SIZE! Trust me. I have the scars.
	 *
	 * 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);
	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)
{
	/* Maximum size of a single call to io_remap_pfn_range. */
	/* I pulled this number out of thin air. */
	const ulong max_chunk_size = 64 * 1024 * 1024;
	ulong chunk_size, mapped_bytes = 0;

	const struct gasket_driver_desc *driver_desc =
		gasket_dev->internal_desc->driver_desc;

	ulong bar_offset, virt_offset;
	struct gasket_mappable_region region_to_map;
	ulong phys_offset, map_length;
	ulong virt_base, phys_base;
	int bar_index, ret;

	ret = gasket_mm_vma_bar_offset(gasket_dev, vma, &bar_offset);
	if (ret)
		return DO_MAP_REGION_INVALID;

	if (!gasket_mm_get_mapping_addrs(mappable_region, bar_offset,
					 vma->vm_end - vma->vm_start,
					 &region_to_map, &virt_offset))
		return DO_MAP_REGION_INVALID;
	phys_offset = region_to_map.start;
	map_length = region_to_map.length_bytes;

	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);
	phys_base = gasket_dev->bar_data[bar_index].phys_base + phys_offset;
	while (mapped_bytes < map_length) {
		/*
		 * io_remap_pfn_range can take a while, so we chunk its
		 * calls and call cond_resched between each.
		 */
		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);
		if (ret) {
			dev_err(gasket_dev->dev,
				"Error remapping PFN range.\n");
			goto fail;
		}
		mapped_bytes += chunk_size;
	}

	return DO_MAP_REGION_SUCCESS;

fail:
	/* Unmap the partial chunk we mapped. */
	mappable_region->length_bytes = mapped_bytes;
	if (gasket_mm_unmap_region(gasket_dev, vma, mappable_region))
		dev_err(gasket_dev->dev,
			"Error unmapping partial region 0x%lx (0x%lx bytes)\n",
			(ulong)virt_offset,
			(ulong)mapped_bytes);

	return DO_MAP_REGION_FAILURE;
}

/* Map a region of coherent memory. */
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;
	const ulong requested_length = vma->vm_end - vma->vm_start;
	int ret;
	ulong permissions;

	if (requested_length == 0 || requested_length >
	    gasket_dev->coherent_buffer.length_bytes) {
		trace_gasket_mmap_exit(-EINVAL);
		return -EINVAL;
	}

	permissions = driver_desc->coherent_buffer_description.permissions;
	if (!gasket_mmap_has_permissions(gasket_dev, vma, permissions)) {
		dev_err(gasket_dev->dev, "Permission checking failed.\n");
		trace_gasket_mmap_exit(-EPERM);
		return -EPERM;
	}

	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
	vma->vm_pgoff = 0;
	ret = dma_mmap_coherent(gasket_dev->dma_dev, vma,
				gasket_dev->coherent_buffer.virt_base,
				gasket_dev->coherent_buffer.phys_base,
				requested_length);
	if (ret) {
		dev_err(gasket_dev->dev,
			"Error mmapping coherent buffer err=%d.\n", ret);
		trace_gasket_mmap_exit(ret);
		return ret;
	}

	/* 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);
	return 0;
}

/* Map a device's BARs into user space. */
static int gasket_mmap(struct file *filp, struct vm_area_struct *vma)
{
	int i, ret;
	int bar_index;
	int has_mapped_anything = 0;
	ulong permissions;
	ulong raw_offset, vma_size;
	bool is_coherent_region;
	const struct gasket_driver_desc *driver_desc;
	struct gasket_dev *gasket_dev = (struct gasket_dev *)filp->private_data;
	const struct gasket_bar_desc *bar_desc;
	struct gasket_mappable_region *map_regions = NULL;
	int num_map_regions = 0;
	enum do_map_region_status map_status;

	driver_desc = gasket_dev->internal_desc->driver_desc;

	if (vma->vm_start & ~PAGE_MASK) {
		dev_err(gasket_dev->dev,
			"Base address not page-aligned: 0x%lx\n",
			vma->vm_start);
		trace_gasket_mmap_exit(-EINVAL);
		return -EINVAL;
	}

	/* Calculate the offset of this range into physical mem. */
	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);

	/*
	 * Check if the raw offset is within a bar region. If not, check if it
	 * is a coherent region.
	 */
	bar_index = gasket_get_bar_index(gasket_dev, raw_offset);
	is_coherent_region = gasket_is_coherent_region(driver_desc, raw_offset);
	if (bar_index < 0 && !is_coherent_region) {
		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;
	}
	if (bar_index > 0 && is_coherent_region) {
		dev_err(gasket_dev->dev,
			"double matching bar and coherent buffers for address "
			"0x%lx\n",
			raw_offset);
		trace_gasket_mmap_exit(bar_index);
		return -EINVAL;
	}

	vma->vm_private_data = gasket_dev;

	if (is_coherent_region)
		return gasket_mmap_coherent(gasket_dev, vma);

	/* Everything in the rest of this function is for normal BAR mapping. */

	/*
	 * Subtract the base of the bar from the raw offset to get the
	 * memory location within the bar to map.
	 */
	bar_desc = &driver_desc->bar_descriptions[bar_index];
	permissions = bar_desc->permissions;
	if (!gasket_mmap_has_permissions(gasket_dev, vma, permissions)) {
		dev_err(gasket_dev->dev, "Permission checking failed.\n");
		trace_gasket_mmap_exit(-EPERM);
		return -EPERM;
	}

	if (driver_desc->get_mappable_regions_cb) {
		ret = driver_desc->get_mappable_regions_cb(gasket_dev,
							   bar_index,
							   &map_regions,
							   &num_map_regions);
		if (ret)
			return ret;
	} else {
		if (!gasket_mmap_has_permissions(gasket_dev, vma,
						 bar_desc->permissions)) {
			dev_err(gasket_dev->dev,
				"Permission checking failed.\n");
			trace_gasket_mmap_exit(-EPERM);
			return -EPERM;
		}
		num_map_regions = bar_desc->num_mappable_regions;
		map_regions = kcalloc(num_map_regions,
				      sizeof(*bar_desc->mappable_regions),
				      GFP_KERNEL);
		if (map_regions) {
			memcpy(map_regions, bar_desc->mappable_regions,
			       num_map_regions *
					sizeof(*bar_desc->mappable_regions));
		}
	}

	if (!map_regions || num_map_regions == 0) {
		dev_err(gasket_dev->dev, "No mappable regions returned!\n");
		return -EINVAL;
	}

	/* Marks the VMA's pages as uncacheable. */
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
	for (i = 0; i < num_map_regions; i++) {
		map_status = do_map_region(gasket_dev, vma, &map_regions[i]);
		/* Try the next region if this one was not mappable. */
		if (map_status == DO_MAP_REGION_INVALID)
			continue;
		if (map_status == DO_MAP_REGION_FAILURE) {
			ret = -ENOMEM;
			goto fail;
		}

		has_mapped_anything = 1;
	}

	kfree(map_regions);

	/* If we could not map any memory, the request was invalid. */
	if (!has_mapped_anything) {
		dev_err(gasket_dev->dev,
			"Map request did not contain a valid region.\n");
		trace_gasket_mmap_exit(-EINVAL);
		return -EINVAL;
	}

	trace_gasket_mmap_exit(0);
	return 0;

fail:
	/* Need to unmap any mapped ranges. */
	num_map_regions = i;
	for (i = 0; i < num_map_regions; i++)
		if (gasket_mm_unmap_region(gasket_dev, vma,
					   &bar_desc->mappable_regions[i]))
			dev_err(gasket_dev->dev, "Error unmapping range %d.\n",
				i);
	kfree(map_regions);

	return ret;
}

/*
 * 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);
	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;
	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;
	}

	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;
	}

	/* 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);
	}

	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);
	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;
	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);

			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;
}

/*
 * Gasket ioctl dispatch function.
 *
 * Check if the ioctl is a generic ioctl. If not, pass the ioctl to the
 * ioctl_handler_cb registered in the driver description.
 * If the ioctl is a generic ioctl, pass it to gasket_ioctl_handler.
 */
static long gasket_ioctl(struct file *filp, uint cmd, ulong arg)
{
	struct gasket_dev *gasket_dev;
	const struct gasket_driver_desc *driver_desc;
	void __user *argp = (void __user *)arg;
	char path[256];

	gasket_dev = (struct gasket_dev *)filp->private_data;
	driver_desc = gasket_dev->internal_desc->driver_desc;
	if (!driver_desc) {
		dev_dbg(gasket_dev->dev,
			"Unable to find device descriptor for file %s\n",
			d_path(&filp->f_path, path, 256));
		return -ENODEV;
	}

	if (!gasket_is_supported_ioctl(cmd)) {
		/*
		 * The ioctl handler is not a standard Gasket callback, since
		 * it requires different arguments. This means we can't use
		 * check_and_invoke_callback.
		 */
		if (driver_desc->ioctl_handler_cb)
			return driver_desc->ioctl_handler_cb(filp, cmd, argp);

		dev_dbg(gasket_dev->dev, "Received unknown ioctl 0x%x\n", cmd);
		return -EINVAL;
	}

	return gasket_handle_ioctl(filp, cmd, argp);
}

/* 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,
	.compat_ioctl = gasket_ioctl,
};

/* Perform final init and marks the device as active. */
int gasket_enable_device(struct gasket_dev *gasket_dev)
{
	int tbl_idx;
	int ret;
	const struct gasket_driver_desc *driver_desc =
		gasket_dev->internal_desc->driver_desc;

	dev_dbg(gasket_dev->dev, "enabling device\n");
	ret = gasket_interrupt_init(gasket_dev);
	if (ret) {
		dev_err(gasket_dev->dev,
			"Critical failure to allocate interrupts: %d\n", ret);
		gasket_interrupt_cleanup(gasket_dev);
		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);
		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]);
	}

	/*
	 * 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;

	/* 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");

	ret = gasket_add_cdev(&gasket_dev->dev_info, &gasket_file_ops,
			      driver_desc->module);
	if (ret)
		return ret;

	return 0;
}
EXPORT_SYMBOL(gasket_enable_device);

static int __gasket_add_device(struct device *parent_dev,
			       struct gasket_internal_desc *internal_desc,
			       struct gasket_dev **gasket_devp)
{
	int ret;
	struct gasket_dev *gasket_dev;
	const struct gasket_driver_desc *driver_desc =
	    internal_desc->driver_desc;

	ret = gasket_alloc_dev(internal_desc, parent_dev, &gasket_dev);
	if (ret)
		return ret;
	if (IS_ERR(gasket_dev->dev_info.device)) {
		dev_err(parent_dev, "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 free_gasket_dev;
	}

	ret = gasket_sysfs_create_mapping(gasket_dev->dev_info.device,
					  gasket_dev);
	if (ret)
		goto remove_device;

	ret = gasket_sysfs_create_entries(gasket_dev->dev_info.device,
					  gasket_sysfs_generic_attrs);
	if (ret)
		goto remove_sysfs_mapping;

	*gasket_devp = gasket_dev;
	return 0;

remove_sysfs_mapping:
	gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
remove_device:
	device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
free_gasket_dev:
	gasket_free_dev(gasket_dev);
	return ret;
}

static void __gasket_remove_device(struct gasket_internal_desc *internal_desc,
				   struct gasket_dev *gasket_dev)
{
	gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
	device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
	gasket_free_dev(gasket_dev);
}

/*
 * Add PCI gasket device.
 *
 * Called by Gasket device probe function.
 * Allocates device metadata and maps device memory.  The device driver must
 * call gasket_enable_device after driver init is complete to place the device
 * in active use.
 */
int gasket_pci_add_device(struct pci_dev *pci_dev,
			  struct gasket_dev **gasket_devp)
{
	int ret;
	struct gasket_internal_desc *internal_desc;
	struct gasket_dev *gasket_dev;
	struct device *parent;

	dev_dbg(&pci_dev->dev, "add PCI gasket device\n");

	mutex_lock(&g_mutex);
	internal_desc = lookup_pci_internal_desc(pci_dev);
	mutex_unlock(&g_mutex);
	if (!internal_desc) {
		dev_err(&pci_dev->dev,
			"PCI add device called for unknown driver type\n");
		return -ENODEV;
	}

	parent = &pci_dev->dev;
	ret = __gasket_add_device(parent, internal_desc, &gasket_dev);
	if (ret)
		return ret;

	gasket_dev->pci_dev = pci_dev;
	ret = gasket_setup_pci(pci_dev, gasket_dev);
	if (ret)
		goto cleanup_pci;

	/*
	 * 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 cleanup_pci;
	}

	*gasket_devp = gasket_dev;
	return 0;

cleanup_pci:
	gasket_cleanup_pci(gasket_dev);
	__gasket_remove_device(internal_desc, gasket_dev);
	return ret;
}
EXPORT_SYMBOL(gasket_pci_add_device);

/* Remove a PCI gasket device. */
void gasket_pci_remove_device(struct pci_dev *pci_dev)
{
	int i;
	struct gasket_internal_desc *internal_desc;
	struct gasket_dev *gasket_dev = NULL;
	/* Find the device desc. */
	mutex_lock(&g_mutex);
	internal_desc = lookup_pci_internal_desc(pci_dev);
	if (!internal_desc) {
		mutex_unlock(&g_mutex);
		return;
	}
	mutex_unlock(&g_mutex);

	/* 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;

	dev_dbg(gasket_dev->dev, "remove %s PCI gasket device\n",
		internal_desc->driver_desc->name);

	gasket_cleanup_pci(gasket_dev);
	__gasket_remove_device(internal_desc, gasket_dev);
}
EXPORT_SYMBOL(gasket_pci_remove_device);

/* Add platform gasket device. Called by Gasket device probe function. */
int gasket_platform_add_device(struct platform_device *pdev,
			       struct gasket_dev **gasket_devp)
{
	int ret;
	struct gasket_internal_desc *internal_desc;
	struct gasket_dev *gasket_dev;
	struct device *parent;

	dev_dbg(&pdev->dev, "add platform gasket device\n");

	mutex_lock(&g_mutex);
	internal_desc = lookup_platform_internal_desc(pdev);
	mutex_unlock(&g_mutex);
	if (!internal_desc) {
		dev_err(&pdev->dev,
			"%s called for unknown driver type\n", __func__);
		return -ENODEV;
	}

	parent = &pdev->dev;
	ret = __gasket_add_device(parent, internal_desc, &gasket_dev);
	if (ret)
		return ret;

	gasket_dev->platform_dev = pdev;
	*gasket_devp = gasket_dev;
	return 0;
}
EXPORT_SYMBOL(gasket_platform_add_device);

/* Remove a platform gasket device. */
void gasket_platform_remove_device(struct platform_device *pdev)
{
	int i;
	struct gasket_internal_desc *internal_desc;
	struct gasket_dev *gasket_dev = NULL;

	/* Find the device desc. */
	mutex_lock(&g_mutex);
	internal_desc = lookup_platform_internal_desc(pdev);
	mutex_unlock(&g_mutex);
	if (!internal_desc)
		return;

	/* 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]->platform_dev == pdev) {
			gasket_dev = internal_desc->devs[i];
			break;
		}
	}
	mutex_unlock(&internal_desc->mutex);

	if (!gasket_dev)
		return;

	dev_dbg(gasket_dev->dev, "remove %s platform gasket device\n",
		internal_desc->driver_desc->name);

	__gasket_remove_device(internal_desc, gasket_dev);
}
EXPORT_SYMBOL(gasket_platform_remove_device);

void gasket_set_dma_device(struct gasket_dev *gasket_dev,
			   struct device *dma_dev)
{
	put_device(gasket_dev->dma_dev);
	gasket_dev->dma_dev = get_device(dma_dev);
}
EXPORT_SYMBOL(gasket_set_dma_device);

/**
 * 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;
	}

	return table[i].snn_name;
}
EXPORT_SYMBOL(gasket_num_name_lookup);

int gasket_reset(struct gasket_dev *gasket_dev)
{
	int ret;

	mutex_lock(&gasket_dev->mutex);
	ret = gasket_reset_nolock(gasket_dev);
	mutex_unlock(&gasket_dev->mutex);
	return ret;
}
EXPORT_SYMBOL(gasket_reset);

int gasket_reset_nolock(struct gasket_dev *gasket_dev)
{
	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;

	ret = driver_desc->device_reset_cb(gasket_dev);
	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.
 */
const struct gasket_driver_desc *gasket_get_driver_desc(struct gasket_dev *dev)
{
	return dev->internal_desc->driver_desc;
}

/* Get the device structure for a given gasket_dev.
 * @dev: pointer to gasket_dev, implementing the requested driver.
 */
struct device *gasket_get_device(struct gasket_dev *dev)
{
	return dev->dev;
}

/**
 * Asynchronously waits on device.
 * @gasket_dev: Device struct.
 * @bar: Bar
 * @offset: Register offset
 * @mask: Register mask
 * @val: Expected value
 * @max_retries: number of sleep periods
 * @delay_ms: Timeout in milliseconds
 *
 * 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)
{
	uint retries = 0;
	u64 tmp;

	while (retries < max_retries) {
		tmp = gasket_dev_read_64(gasket_dev, bar, offset);
		if ((tmp & mask) == val)
			return 0;
		msleep(delay_ms);
		retries++;
	}
	dev_dbg(gasket_dev->dev, "%s timeout: reg %llx timeout (%llu ms)\n",
		__func__, offset, max_retries * delay_ms);
	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_debug("Loading %s driver version %s\n", driver_desc->name,
		 driver_desc->driver_version);
	/* 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);

	if (desc_idx == -1) {
		pr_err("too many drivers loaded, max %d\n",
		       GASKET_FRAMEWORK_DESC_MAX);
		return -EBUSY;
	}

	internal = &g_descs[desc_idx];
	mutex_init(&internal->mutex);
	memset(internal->devs, 0, sizeof(struct gasket_dev *) * GASKET_DEV_MAX);
	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;
	}

	ret = register_chrdev_region(MKDEV(driver_desc->major,
					   driver_desc->minor), GASKET_DEV_MAX,
				     driver_desc->name);
	if (ret) {
		pr_err("cannot register %s char driver [ret=%d]\n",
		       driver_desc->name, ret);
		goto destroy_class;
	}

	return 0;

destroy_class:
	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;
		}
	}

	if (!internal_desc) {
		mutex_unlock(&g_mutex);
		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);

	class_destroy(internal_desc->class);

	/* Finally, effectively "remove" the driver. */
	g_descs[desc_idx].driver_desc = NULL;
	mutex_unlock(&g_mutex);

	pr_debug("removed %s driver\n", driver_desc->name);
}
EXPORT_SYMBOL(gasket_unregister_device);

static int __init gasket_init(void)
{
	int i;

	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;
}

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);
