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

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

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

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

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

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

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