text:
#define pr_fmt(fmt)     "DMAR: " fmt

#include <linux/pci.h>
#include <linux/dmar.h>
#include <linux/iova.h>
#include <linux/intel-iommu.h>
#include <linux/timer.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/tboot.h>
#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/iommu.h>
#include <asm/irq_remapping.h>
#include <asm/iommu_table.h>

#include "irq_remapping.h"

typedef int (*dmar_res_handler_t)(struct acpi_dmar_header *, void *);
struct dmar_res_callback {
	dmar_res_handler_t	cb[ACPI_DMAR_TYPE_RESERVED];
	void			*arg[ACPI_DMAR_TYPE_RESERVED];
	bool			ignore_unhandled;
	bool			print_entry;
};

/*
 * Assumptions:
 * 1) The hotplug framework guarentees that DMAR unit will be hot-added
 *    before IO devices managed by that unit.
 * 2) The hotplug framework guarantees that DMAR unit will be hot-removed
 *    after IO devices managed by that unit.
 * 3) Hotplug events are rare.
 *
 * Locking rules for DMA and interrupt remapping related global data structures:
 * 1) Use dmar_global_lock in process context
 * 2) Use RCU in interrupt context
 */
DECLARE_RWSEM(dmar_global_lock);
LIST_HEAD(dmar_drhd_units);

struct acpi_table_header * __initdata dmar_tbl;
static acpi_size dmar_tbl_size;
static int dmar_dev_scope_status = 1;
static unsigned long dmar_seq_ids[BITS_TO_LONGS(DMAR_UNITS_SUPPORTED)];

static int alloc_iommu(struct dmar_drhd_unit *drhd);
static void free_iommu(struct intel_iommu *iommu);

static void dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
{
	/*
	 * add INCLUDE_ALL at the tail, so scan the list will find it at
	 * the very end.
	 */
	if (drhd->include_all)
		list_add_tail_rcu(&drhd->list, &dmar_drhd_units);
	else
		list_add_rcu(&drhd->list, &dmar_drhd_units);
}

void *dmar_alloc_dev_scope(void *start, void *end, int *cnt)
{
	struct acpi_dmar_device_scope *scope;

	*cnt = 0;
	while (start < end) {
		scope = start;
		if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_NAMESPACE ||
		    scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
		    scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
			(*cnt)++;
		else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC &&
			scope->entry_type != ACPI_DMAR_SCOPE_TYPE_HPET) {
			pr_warn("Unsupported device scope\n");
		}
		start += scope->length;
	}
	if (*cnt == 0)
		return NULL;

	return kcalloc(*cnt, sizeof(struct dmar_dev_scope), GFP_KERNEL);
}

void dmar_free_dev_scope(struct dmar_dev_scope **devices, int *cnt)
{
	int i;
	struct device *tmp_dev;

	if (*devices && *cnt) {
		for_each_active_dev_scope(*devices, *cnt, i, tmp_dev)
			put_device(tmp_dev);
		kfree(*devices);
	}

	*devices = NULL;
	*cnt = 0;
}

/* Optimize out kzalloc()/kfree() for normal cases */
static char dmar_pci_notify_info_buf[64];

static struct dmar_pci_notify_info *
dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event)
{
	int level = 0;
	size_t size;
	struct pci_dev *tmp;
	struct dmar_pci_notify_info *info;

	BUG_ON(dev->is_virtfn);

	/* Only generate path[] for device addition event */
	if (event == BUS_NOTIFY_ADD_DEVICE)
		for (tmp = dev; tmp; tmp = tmp->bus->self)
			level++;

	size = sizeof(*info) + level * sizeof(struct acpi_dmar_pci_path);
	if (size <= sizeof(dmar_pci_notify_info_buf)) {
		info = (struct dmar_pci_notify_info *)dmar_pci_notify_info_buf;
	} else {
		info = kzalloc(size, GFP_KERNEL);
		if (!info) {
			pr_warn("Out of memory when allocating notify_info "
				"for %s.\n", pci_name(dev));
			if (dmar_dev_scope_status == 0)
				dmar_dev_scope_status = -ENOMEM;
			return NULL;
		}
	}

	info->event = event;
	info->dev = dev;
	info->seg = pci_domain_nr(dev->bus);
	info->level = level;
	if (event == BUS_NOTIFY_ADD_DEVICE) {
		for (tmp = dev; tmp; tmp = tmp->bus->self) {
			level--;
			info->path[level].bus = tmp->bus->number;
			info->path[level].device = PCI_SLOT(tmp->devfn);
			info->path[level].function = PCI_FUNC(tmp->devfn);
			if (pci_is_root_bus(tmp->bus))
				info->bus = tmp->bus->number;
		}
	}

	return info;
}

static inline void dmar_free_pci_notify_info(struct dmar_pci_notify_info *info)
{
	if ((void *)info != dmar_pci_notify_info_buf)
		kfree(info);
}

static bool dmar_match_pci_path(struct dmar_pci_notify_info *info, int bus,
				struct acpi_dmar_pci_path *path, int count)
{
	int i;

	if (info->bus != bus)
		goto fallback;
	if (info->level != count)
		goto fallback;

	for (i = 0; i < count; i++) {
		if (path[i].device != info->path[i].device ||
		    path[i].function != info->path[i].function)
			goto fallback;
	}

	return true;

fallback:

	if (count != 1)
		return false;

	i = info->level - 1;
	if (bus              == info->path[i].bus &&
	    path[0].device   == info->path[i].device &&
	    path[0].function == info->path[i].function) {
		pr_info(FW_BUG "RMRR entry for device %02x:%02x.%x is broken - applying workaround\n",
			bus, path[0].device, path[0].function);
		return true;
	}

	return false;
}

/* Return: > 0 if match found, 0 if no match found, < 0 if error happens */
int dmar_insert_dev_scope(struct dmar_pci_notify_info *info,
			  void *start, void*end, u16 segment,
			  struct dmar_dev_scope *devices,
			  int devices_cnt)
{
	int i, level;
	struct device *tmp, *dev = &info->dev->dev;
	struct acpi_dmar_device_scope *scope;
	struct acpi_dmar_pci_path *path;

	if (segment != info->seg)
		return 0;

	for (; start < end; start += scope->length) {
		scope = start;
		if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_ENDPOINT &&
		    scope->entry_type != ACPI_DMAR_SCOPE_TYPE_BRIDGE)
			continue;

		path = (struct acpi_dmar_pci_path *)(scope + 1);
		level = (scope->length - sizeof(*scope)) / sizeof(*path);
		if (!dmar_match_pci_path(info, scope->bus, path, level))
			continue;

		if ((scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT) ^
		    (info->dev->hdr_type == PCI_HEADER_TYPE_NORMAL)) {
			pr_warn("Device scope type does not match for %s\n",
				pci_name(info->dev));
			return -EINVAL;
		}

		for_each_dev_scope(devices, devices_cnt, i, tmp)
			if (tmp == NULL) {
				devices[i].bus = info->dev->bus->number;
				devices[i].devfn = info->dev->devfn;
				rcu_assign_pointer(devices[i].dev,
						   get_device(dev));
				return 1;
			}
		BUG_ON(i >= devices_cnt);
	}

	return 0;
}

int dmar_remove_dev_scope(struct dmar_pci_notify_info *info, u16 segment,
			  struct dmar_dev_scope *devices, int count)
{
	int index;
	struct device *tmp;

	if (info->seg != segment)
		return 0;

	for_each_active_dev_scope(devices, count, index, tmp)
		if (tmp == &info->dev->dev) {
			RCU_INIT_POINTER(devices[index].dev, NULL);
			synchronize_rcu();
			put_device(tmp);
			return 1;
		}

	return 0;
}

static int dmar_pci_bus_add_dev(struct dmar_pci_notify_info *info)
{
	int ret = 0;
	struct dmar_drhd_unit *dmaru;
	struct acpi_dmar_hardware_unit *drhd;

	for_each_drhd_unit(dmaru) {
		if (dmaru->include_all)
			continue;

		drhd = container_of(dmaru->hdr,
				    struct acpi_dmar_hardware_unit, header);
		ret = dmar_insert_dev_scope(info, (void *)(drhd + 1),
				((void *)drhd) + drhd->header.length,
				dmaru->segment,
				dmaru->devices, dmaru->devices_cnt);
		if (ret != 0)
			break;
	}
	if (ret >= 0)
		ret = dmar_iommu_notify_scope_dev(info);
	if (ret < 0 && dmar_dev_scope_status == 0)
		dmar_dev_scope_status = ret;

	return ret;
}

static void  dmar_pci_bus_del_dev(struct dmar_pci_notify_info *info)
{
	struct dmar_drhd_unit *dmaru;

	for_each_drhd_unit(dmaru)
		if (dmar_remove_dev_scope(info, dmaru->segment,
			dmaru->devices, dmaru->devices_cnt))
			break;
	dmar_iommu_notify_scope_dev(info);
}

static int dmar_pci_bus_notifier(struct notifier_block *nb,
				 unsigned long action, void *data)
{
	struct pci_dev *pdev = to_pci_dev(data);
	struct dmar_pci_notify_info *info;

	/* Only care about add/remove events for physical functions */
	if (pdev->is_virtfn)
		return NOTIFY_DONE;
	if (action != BUS_NOTIFY_ADD_DEVICE &&
	    action != BUS_NOTIFY_REMOVED_DEVICE)
		return NOTIFY_DONE;

	info = dmar_alloc_pci_notify_info(pdev, action);
	if (!info)
		return NOTIFY_DONE;

	down_write(&dmar_global_lock);
	if (action == BUS_NOTIFY_ADD_DEVICE)
		dmar_pci_bus_add_dev(info);
	else if (action == BUS_NOTIFY_REMOVED_DEVICE)
		dmar_pci_bus_del_dev(info);
	up_write(&dmar_global_lock);

	dmar_free_pci_notify_info(info);

	return NOTIFY_OK;
}

static struct notifier_block dmar_pci_bus_nb = {
	.notifier_call = dmar_pci_bus_notifier,
	.priority = INT_MIN,
};

static struct dmar_drhd_unit *
dmar_find_dmaru(struct acpi_dmar_hardware_unit *drhd)
{
	struct dmar_drhd_unit *dmaru;

	list_for_each_entry_rcu(dmaru, &dmar_drhd_units, list)
		if (dmaru->segment == drhd->segment &&
		    dmaru->reg_base_addr == drhd->address)
			return dmaru;

	return NULL;
}

/**
 * dmar_parse_one_drhd - parses exactly one DMA remapping hardware definition
 * structure which uniquely represent one DMA remapping hardware unit
 * present in the platform
 */
static int dmar_parse_one_drhd(struct acpi_dmar_header *header, void *arg)
{
	struct acpi_dmar_hardware_unit *drhd;
	struct dmar_drhd_unit *dmaru;
	int ret = 0;

	drhd = (struct acpi_dmar_hardware_unit *)header;
	dmaru = dmar_find_dmaru(drhd);
	if (dmaru)
		goto out;

	dmaru = kzalloc(sizeof(*dmaru) + header->length, GFP_KERNEL);
	if (!dmaru)
		return -ENOMEM;

	/*
	 * If header is allocated from slab by ACPI _DSM method, we need to
	 * copy the content because the memory buffer will be freed on return.
	 */
	dmaru->hdr = (void *)(dmaru + 1);
	memcpy(dmaru->hdr, header, header->length);
	dmaru->reg_base_addr = drhd->address;
	dmaru->segment = drhd->segment;
	dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
	dmaru->devices = dmar_alloc_dev_scope((void *)(drhd + 1),
					      ((void *)drhd) + drhd->header.length,
					      &dmaru->devices_cnt);
	if (dmaru->devices_cnt && dmaru->devices == NULL) {
		kfree(dmaru);
		return -ENOMEM;
	}

	ret = alloc_iommu(dmaru);
	if (ret) {
		dmar_free_dev_scope(&dmaru->devices,
				    &dmaru->devices_cnt);
		kfree(dmaru);
		return ret;
	}
	dmar_register_drhd_unit(dmaru);

out:
	if (arg)
		(*(int *)arg)++;

	return 0;
}

static void dmar_free_drhd(struct dmar_drhd_unit *dmaru)
{
	if (dmaru->devices && dmaru->devices_cnt)
		dmar_free_dev_scope(&dmaru->devices, &dmaru->devices_cnt);
	if (dmaru->iommu)
		free_iommu(dmaru->iommu);
	kfree(dmaru);
}

static int __init dmar_parse_one_andd(struct acpi_dmar_header *header,
				      void *arg)
{
	struct acpi_dmar_andd *andd = (void *)header;

	/* Check for NUL termination within the designated length */
	if (strnlen(andd->device_name, header->length - 8) == header->length - 8) {
		WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
			   "Your BIOS is broken; ANDD object name is not NUL-terminated\n"
			   "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
			   dmi_get_system_info(DMI_BIOS_VENDOR),
			   dmi_get_system_info(DMI_BIOS_VERSION),
			   dmi_get_system_info(DMI_PRODUCT_VERSION));
		return -EINVAL;
	}
	pr_info("ANDD device: %x name: %s\n", andd->device_number,
		andd->device_name);

	return 0;
}

#ifdef CONFIG_ACPI_NUMA
static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg)
{
	struct acpi_dmar_rhsa *rhsa;
	struct dmar_drhd_unit *drhd;

	rhsa = (struct acpi_dmar_rhsa *)header;
	for_each_drhd_unit(drhd) {
		if (drhd->reg_base_addr == rhsa->base_address) {
			int node = acpi_map_pxm_to_node(rhsa->proximity_domain);

			if (!node_online(node))
				node = -1;
			drhd->iommu->node = node;
			return 0;
		}
	}
	WARN_TAINT(
		1, TAINT_FIRMWARE_WORKAROUND,
		"Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n"
		"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
		drhd->reg_base_addr,
		dmi_get_system_info(DMI_BIOS_VENDOR),
		dmi_get_system_info(DMI_BIOS_VERSION),
		dmi_get_system_info(DMI_PRODUCT_VERSION));

	return 0;
}
#else
#define	dmar_parse_one_rhsa		dmar_res_noop
#endif

static void __init
dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
{
	struct acpi_dmar_hardware_unit *drhd;
	struct acpi_dmar_reserved_memory *rmrr;
	struct acpi_dmar_atsr *atsr;
	struct acpi_dmar_rhsa *rhsa;

	switch (header->type) {
	case ACPI_DMAR_TYPE_HARDWARE_UNIT:
		drhd = container_of(header, struct acpi_dmar_hardware_unit,
				    header);
		pr_info("DRHD base: %#016Lx flags: %#x\n",
			(unsigned long long)drhd->address, drhd->flags);
		break;
	case ACPI_DMAR_TYPE_RESERVED_MEMORY:
		rmrr = container_of(header, struct acpi_dmar_reserved_memory,
				    header);
		pr_info("RMRR base: %#016Lx end: %#016Lx\n",
			(unsigned long long)rmrr->base_address,
			(unsigned long long)rmrr->end_address);
		break;
	case ACPI_DMAR_TYPE_ROOT_ATS:
		atsr = container_of(header, struct acpi_dmar_atsr, header);
		pr_info("ATSR flags: %#x\n", atsr->flags);
		break;
	case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
		rhsa = container_of(header, struct acpi_dmar_rhsa, header);
		pr_info("RHSA base: %#016Lx proximity domain: %#x\n",
		       (unsigned long long)rhsa->base_address,
		       rhsa->proximity_domain);
		break;
	case ACPI_DMAR_TYPE_NAMESPACE:
		/* We don't print this here because we need to sanity-check
		   it first. So print it in dmar_parse_one_andd() instead. */
		break;
	}
}

/**
 * dmar_table_detect - checks to see if the platform supports DMAR devices
 */
static int __init dmar_table_detect(void)
{
	acpi_status status = AE_OK;

	/* if we could find DMAR table, then there are DMAR devices */
	status = acpi_get_table_with_size(ACPI_SIG_DMAR, 0,
				(struct acpi_table_header **)&dmar_tbl,
				&dmar_tbl_size);

	if (ACPI_SUCCESS(status) && !dmar_tbl) {
		pr_warn("Unable to map DMAR\n");
		status = AE_NOT_FOUND;
	}

	return (ACPI_SUCCESS(status) ? 1 : 0);
}

static int dmar_walk_remapping_entries(struct acpi_dmar_header *start,
				       size_t len, struct dmar_res_callback *cb)
{
	int ret = 0;
	struct acpi_dmar_header *iter, *next;
	struct acpi_dmar_header *end = ((void *)start) + len;

	for (iter = start; iter < end && ret == 0; iter = next) {
		next = (void *)iter + iter->length;
		if (iter->length == 0) {
			/* Avoid looping forever on bad ACPI tables */
			pr_debug(FW_BUG "Invalid 0-length structure\n");
			break;
		} else if (next > end) {
			/* Avoid passing table end */
			pr_warn(FW_BUG "Record passes table end\n");
			ret = -EINVAL;
			break;
		}

		if (cb->print_entry)
			dmar_table_print_dmar_entry(iter);

		if (iter->type >= ACPI_DMAR_TYPE_RESERVED) {
			/* continue for forward compatibility */
			pr_debug("Unknown DMAR structure type %d\n",
				 iter->type);
		} else if (cb->cb[iter->type]) {
			ret = cb->cb[iter->type](iter, cb->arg[iter->type]);
		} else if (!cb->ignore_unhandled) {
			pr_warn("No handler for DMAR structure type %d\n",
				iter->type);
			ret = -EINVAL;
		}
	}

	return ret;
}

static inline int dmar_walk_dmar_table(struct acpi_table_dmar *dmar,
				       struct dmar_res_callback *cb)
{
	return dmar_walk_remapping_entries((void *)(dmar + 1),
			dmar->header.length - sizeof(*dmar), cb);
}

/**
 * parse_dmar_table - parses the DMA reporting table
 */
static int __init
parse_dmar_table(void)
{
	struct acpi_table_dmar *dmar;
	int ret = 0;
	int drhd_count = 0;
	struct dmar_res_callback cb = {
		.print_entry = true,
		.ignore_unhandled = true,
		.arg[ACPI_DMAR_TYPE_HARDWARE_UNIT] = &drhd_count,
		.cb[ACPI_DMAR_TYPE_HARDWARE_UNIT] = &dmar_parse_one_drhd,
		.cb[ACPI_DMAR_TYPE_RESERVED_MEMORY] = &dmar_parse_one_rmrr,
		.cb[ACPI_DMAR_TYPE_ROOT_ATS] = &dmar_parse_one_atsr,
		.cb[ACPI_DMAR_TYPE_HARDWARE_AFFINITY] = &dmar_parse_one_rhsa,
		.cb[ACPI_DMAR_TYPE_NAMESPACE] = &dmar_parse_one_andd,
	};

	/*
	 * Do it again, earlier dmar_tbl mapping could be mapped with
	 * fixed map.
	 */
	dmar_table_detect();

	/*
	 * ACPI tables may not be DMA protected by tboot, so use DMAR copy
	 * SINIT saved in SinitMleData in TXT heap (which is DMA protected)
	 */
	dmar_tbl = tboot_get_dmar_table(dmar_tbl);

	dmar = (struct acpi_table_dmar *)dmar_tbl;
	if (!dmar)
		return -ENODEV;

	if (dmar->width < PAGE_SHIFT - 1) {
		pr_warn("Invalid DMAR haw\n");
		return -EINVAL;
	}

	pr_info("Host address width %d\n", dmar->width + 1);
	ret = dmar_walk_dmar_table(dmar, &cb);
	if (ret == 0 && drhd_count == 0)
		pr_warn(FW_BUG "No DRHD structure found in DMAR table\n");

	return ret;
}

static int dmar_pci_device_match(struct dmar_dev_scope devices[],
				 int cnt, struct pci_dev *dev)
{
	int index;
	struct device *tmp;

	while (dev) {
		for_each_active_dev_scope(devices, cnt, index, tmp)
			if (dev_is_pci(tmp) && dev == to_pci_dev(tmp))
				return 1;

		/* Check our parent */
		dev = dev->bus->self;
	}

	return 0;
}

struct dmar_drhd_unit *
dmar_find_matched_drhd_unit(struct pci_dev *dev)
{
	struct dmar_drhd_unit *dmaru;
	struct acpi_dmar_hardware_unit *drhd;

	dev = pci_physfn(dev);

	rcu_read_lock();
	for_each_drhd_unit(dmaru) {
		drhd = container_of(dmaru->hdr,
				    struct acpi_dmar_hardware_unit,
				    header);

		if (dmaru->include_all &&
		    drhd->segment == pci_domain_nr(dev->bus))
			goto out;

		if (dmar_pci_device_match(dmaru->devices,
					  dmaru->devices_cnt, dev))
			goto out;
	}
	dmaru = NULL;
out:
	rcu_read_unlock();

	return dmaru;
}

static void __init dmar_acpi_insert_dev_scope(u8 device_number,
					      struct acpi_device *adev)
{
	struct dmar_drhd_unit *dmaru;
	struct acpi_dmar_hardware_unit *drhd;
	struct acpi_dmar_device_scope *scope;
	struct device *tmp;
	int i;
	struct acpi_dmar_pci_path *path;

	for_each_drhd_unit(dmaru) {
		drhd = container_of(dmaru->hdr,
				    struct acpi_dmar_hardware_unit,
				    header);

		for (scope = (void *)(drhd + 1);
		     (unsigned long)scope < ((unsigned long)drhd) + drhd->header.length;
		     scope = ((void *)scope) + scope->length) {
			if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_NAMESPACE)
				continue;
			if (scope->enumeration_id != device_number)
				continue;

			path = (void *)(scope + 1);
			pr_info("ACPI device \"%s\" under DMAR at %llx as %02x:%02x.%d\n",
				dev_name(&adev->dev), dmaru->reg_base_addr,
				scope->bus, path->device, path->function);
			for_each_dev_scope(dmaru->devices, dmaru->devices_cnt, i, tmp)
				if (tmp == NULL) {
					dmaru->devices[i].bus = scope->bus;
					dmaru->devices[i].devfn = PCI_DEVFN(path->device,
									    path->function);
					rcu_assign_pointer(dmaru->devices[i].dev,
							   get_device(&adev->dev));
					return;
				}
			BUG_ON(i >= dmaru->devices_cnt);
		}
	}
	pr_warn("No IOMMU scope found for ANDD enumeration ID %d (%s)\n",
		device_number, dev_name(&adev->dev));
}

static int __init dmar_acpi_dev_scope_init(void)
{
	struct acpi_dmar_andd *andd;

	if (dmar_tbl == NULL)
		return -ENODEV;

	for (andd = (void *)dmar_tbl + sizeof(struct acpi_table_dmar);
	     ((unsigned long)andd) < ((unsigned long)dmar_tbl) + dmar_tbl->length;
	     andd = ((void *)andd) + andd->header.length) {
		if (andd->header.type == ACPI_DMAR_TYPE_NAMESPACE) {
			acpi_handle h;
			struct acpi_device *adev;

			if (!ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT,
							  andd->device_name,
							  &h))) {
				pr_err("Failed to find handle for ACPI object %s\n",
				       andd->device_name);
				continue;
			}
			if (acpi_bus_get_device(h, &adev)) {
				pr_err("Failed to get device for ACPI object %s\n",
				       andd->device_name);
				continue;
			}
			dmar_acpi_insert_dev_scope(andd->device_number, adev);
		}
	}
	return 0;
}

int __init dmar_dev_scope_init(void)
{
	struct pci_dev *dev = NULL;
	struct dmar_pci_notify_info *info;

	if (dmar_dev_scope_status != 1)
		return dmar_dev_scope_status;

	if (list_empty(&dmar_drhd_units)) {
		dmar_dev_scope_status = -ENODEV;
	} else {
		dmar_dev_scope_status = 0;

		dmar_acpi_dev_scope_init();

		for_each_pci_dev(dev) {
			if (dev->is_virtfn)
				continue;

			info = dmar_alloc_pci_notify_info(dev,
					BUS_NOTIFY_ADD_DEVICE);
			if (!info) {
				return dmar_dev_scope_status;
			} else {
				dmar_pci_bus_add_dev(info);
				dmar_free_pci_notify_info(info);
			}
		}

		bus_register_notifier(&pci_bus_type, &dmar_pci_bus_nb);
	}

	return dmar_dev_scope_status;
}

int __init dmar_table_init(void)
{
	static int dmar_table_initialized;
	int ret;

	if (dmar_table_initialized == 0) {
		ret = parse_dmar_table();
		if (ret < 0) {
			if (ret != -ENODEV)
				pr_info("Parse DMAR table failure.\n");
		} else  if (list_empty(&dmar_drhd_units)) {
			pr_info("No DMAR devices found\n");
			ret = -ENODEV;
		}

		if (ret < 0)
			dmar_table_initialized = ret;
		else
			dmar_table_initialized = 1;
	}

	return dmar_table_initialized < 0 ? dmar_table_initialized : 0;
}

static void warn_invalid_dmar(u64 addr, const char *message)
{
	WARN_TAINT_ONCE(
		1, TAINT_FIRMWARE_WORKAROUND,
		"Your BIOS is broken; DMAR reported at address %llx%s!\n"
		"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
		addr, message,
		dmi_get_system_info(DMI_BIOS_VENDOR),
		dmi_get_system_info(DMI_BIOS_VERSION),
		dmi_get_system_info(DMI_PRODUCT_VERSION));
}

static int __ref
dmar_validate_one_drhd(struct acpi_dmar_header *entry, void *arg)
{
	struct acpi_dmar_hardware_unit *drhd;
	void __iomem *addr;
	u64 cap, ecap;

	drhd = (void *)entry;
	if (!drhd->address) {
		warn_invalid_dmar(0, "");
		return -EINVAL;
	}

	if (arg)
		addr = ioremap(drhd->address, VTD_PAGE_SIZE);
	else
		addr = early_ioremap(drhd->address, VTD_PAGE_SIZE);
	if (!addr) {
		pr_warn("Can't validate DRHD address: %llx\n", drhd->address);
		return -EINVAL;
	}

	cap = dmar_readq(addr + DMAR_CAP_REG);
	ecap = dmar_readq(addr + DMAR_ECAP_REG);

	if (arg)
		iounmap(addr);
	else
		early_iounmap(addr, VTD_PAGE_SIZE);

	if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) {
		warn_invalid_dmar(drhd->address, " returns all ones");
		return -EINVAL;
	}

	return 0;
}

int __init detect_intel_iommu(void)
{
	int ret;
	struct dmar_res_callback validate_drhd_cb = {
		.cb[ACPI_DMAR_TYPE_HARDWARE_UNIT] = &dmar_validate_one_drhd,
		.ignore_unhandled = true,
	};

	down_write(&dmar_global_lock);
	ret = dmar_table_detect();
	if (ret)
		ret = !dmar_walk_dmar_table((struct acpi_table_dmar *)dmar_tbl,
					    &validate_drhd_cb);
	if (ret && !no_iommu && !iommu_detected && !dmar_disabled) {
		iommu_detected = 1;
		/* Make sure ACS will be enabled */
		pci_request_acs();
	}

#ifdef CONFIG_X86
	if (ret)
		x86_init.iommu.iommu_init = intel_iommu_init;
#endif

	early_acpi_os_unmap_memory((void __iomem *)dmar_tbl, dmar_tbl_size);
	dmar_tbl = NULL;
	up_write(&dmar_global_lock);

	return ret ? 1 : -ENODEV;
}

static void unmap_iommu(struct intel_iommu *iommu)
{
	iounmap(iommu->reg);
	release_mem_region(iommu->reg_phys, iommu->reg_size);
}

/**
 * map_iommu: map the iommu's registers
 * @iommu: the iommu to map
 * @phys_addr: the physical address of the base resgister
 *
 * Memory map the iommu's registers.  Start w/ a single page, and
 * possibly expand if that turns out to be insufficent.
 */
static int map_iommu(struct intel_iommu *iommu, u64 phys_addr)
{
	int map_size, err=0;

	iommu->reg_phys = phys_addr;
	iommu->reg_size = VTD_PAGE_SIZE;

	if (!request_mem_region(iommu->reg_phys, iommu->reg_size, iommu->name)) {
		pr_err("Can't reserve memory\n");
		err = -EBUSY;
		goto out;
	}

	iommu->reg = ioremap(iommu->reg_phys, iommu->reg_size);
	if (!iommu->reg) {
		pr_err("Can't map the region\n");
		err = -ENOMEM;
		goto release;
	}

	iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG);
	iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);

	if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) {
		err = -EINVAL;
		warn_invalid_dmar(phys_addr, " returns all ones");
		goto unmap;
	}

	/* the registers might be more than one page */
	map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
			 cap_max_fault_reg_offset(iommu->cap));
	map_size = VTD_PAGE_ALIGN(map_size);
	if (map_size > iommu->reg_size) {
		iounmap(iommu->reg);
		release_mem_region(iommu->reg_phys, iommu->reg_size);
		iommu->reg_size = map_size;
		if (!request_mem_region(iommu->reg_phys, iommu->reg_size,
					iommu->name)) {
			pr_err("Can't reserve memory\n");
			err = -EBUSY;
			goto out;
		}
		iommu->reg = ioremap(iommu->reg_phys, iommu->reg_size);
		if (!iommu->reg) {
			pr_err("Can't map the region\n");
			err = -ENOMEM;
			goto release;
		}
	}
	err = 0;
	goto out;

unmap:
	iounmap(iommu->reg);
release:
	release_mem_region(iommu->reg_phys, iommu->reg_size);
out:
	return err;
}

static int dmar_alloc_seq_id(struct intel_iommu *iommu)
{
	iommu->seq_id = find_first_zero_bit(dmar_seq_ids,
					    DMAR_UNITS_SUPPORTED);
	if (iommu->seq_id >= DMAR_UNITS_SUPPORTED) {
		iommu->seq_id = -1;
	} else {
		set_bit(iommu->seq_id, dmar_seq_ids);
		sprintf(iommu->name, "dmar%d", iommu->seq_id);
	}

	return iommu->seq_id;
}

static void dmar_free_seq_id(struct intel_iommu *iommu)
{
	if (iommu->seq_id >= 0) {
		clear_bit(iommu->seq_id, dmar_seq_ids);
		iommu->seq_id = -1;
	}
}

static int alloc_iommu(struct dmar_drhd_unit *drhd)
{
	struct intel_iommu *iommu;
	u32 ver, sts;
	int agaw = 0;
	int msagaw = 0;
	int err;

	if (!drhd->reg_base_addr) {
		warn_invalid_dmar(0, "");
		return -EINVAL;
	}

	iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
	if (!iommu)
		return -ENOMEM;

	if (dmar_alloc_seq_id(iommu) < 0) {
		pr_err("Failed to allocate seq_id\n");
		err = -ENOSPC;
		goto error;
	}

	err = map_iommu(iommu, drhd->reg_base_addr);
	if (err) {
		pr_err("Failed to map %s\n", iommu->name);
		goto error_free_seq_id;
	}

	err = -EINVAL;
	agaw = iommu_calculate_agaw(iommu);
	if (agaw < 0) {
		pr_err("Cannot get a valid agaw for iommu (seq_id = %d)\n",
			iommu->seq_id);
		goto err_unmap;
	}
	msagaw = iommu_calculate_max_sagaw(iommu);
	if (msagaw < 0) {
		pr_err("Cannot get a valid max agaw for iommu (seq_id = %d)\n",
			iommu->seq_id);
		goto err_unmap;
	}
	iommu->agaw = agaw;
	iommu->msagaw = msagaw;
	iommu->segment = drhd->segment;

	iommu->node = -1;

	ver = readl(iommu->reg + DMAR_VER_REG);
	pr_info("%s: reg_base_addr %llx ver %d:%d cap %llx ecap %llx\n",
		iommu->name,
		(unsigned long long)drhd->reg_base_addr,
		DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver),
		(unsigned long long)iommu->cap,
		(unsigned long long)iommu->ecap);

	/* Reflect status in gcmd */
	sts = readl(iommu->reg + DMAR_GSTS_REG);
	if (sts & DMA_GSTS_IRES)
		iommu->gcmd |= DMA_GCMD_IRE;
	if (sts & DMA_GSTS_TES)
		iommu->gcmd |= DMA_GCMD_TE;
	if (sts & DMA_GSTS_QIES)
		iommu->gcmd |= DMA_GCMD_QIE;

	raw_spin_lock_init(&iommu->register_lock);

	if (intel_iommu_enabled) {
		iommu->iommu_dev = iommu_device_create(NULL, iommu,
						       intel_iommu_groups,
						       "%s", iommu->name);

		if (IS_ERR(iommu->iommu_dev)) {
			err = PTR_ERR(iommu->iommu_dev);
			goto err_unmap;
		}
	}

	drhd->iommu = iommu;

	return 0;

err_unmap:
	unmap_iommu(iommu);
error_free_seq_id:
	dmar_free_seq_id(iommu);
error:
	kfree(iommu);
	return err;
}

static void free_iommu(struct intel_iommu *iommu)
{
	iommu_device_destroy(iommu->iommu_dev);

	if (iommu->irq) {
		if (iommu->pr_irq) {
			free_irq(iommu->pr_irq, iommu);
			dmar_free_hwirq(iommu->pr_irq);
			iommu->pr_irq = 0;
		}
		free_irq(iommu->irq, iommu);
		dmar_free_hwirq(iommu->irq);
		iommu->irq = 0;
	}

	if (iommu->qi) {
		free_page((unsigned long)iommu->qi->desc);
		kfree(iommu->qi->desc_status);
		kfree(iommu->qi);
	}

	if (iommu->reg)
		unmap_iommu(iommu);

	dmar_free_seq_id(iommu);
	kfree(iommu);
}

/*
 * Reclaim all the submitted descriptors which have completed its work.
 */
static inline void reclaim_free_desc(struct q_inval *qi)
{
	while (qi->desc_status[qi->free_tail] == QI_DONE ||
	       qi->desc_status[qi->free_tail] == QI_ABORT) {
		qi->desc_status[qi->free_tail] = QI_FREE;
		qi->free_tail = (qi->free_tail + 1) % QI_LENGTH;
		qi->free_cnt++;
	}
}

static int qi_check_fault(struct intel_iommu *iommu, int index)
{
	u32 fault;
	int head, tail;
	struct q_inval *qi = iommu->qi;
	int wait_index = (index + 1) % QI_LENGTH;

	if (qi->desc_status[wait_index] == QI_ABORT)
		return -EAGAIN;

	fault = readl(iommu->reg + DMAR_FSTS_REG);

	/*
	 * If IQE happens, the head points to the descriptor associated
	 * with the error. No new descriptors are fetched until the IQE
	 * is cleared.
	 */
	if (fault & DMA_FSTS_IQE) {
		head = readl(iommu->reg + DMAR_IQH_REG);
		if ((head >> DMAR_IQ_SHIFT) == index) {
			pr_err("VT-d detected invalid descriptor: "
				"low=%llx, high=%llx\n",
				(unsigned long long)qi->desc[index].low,
				(unsigned long long)qi->desc[index].high);
			memcpy(&qi->desc[index], &qi->desc[wait_index],
					sizeof(struct qi_desc));
			__iommu_flush_cache(iommu, &qi->desc[index],
					sizeof(struct qi_desc));
			writel(DMA_FSTS_IQE, iommu->reg + DMAR_FSTS_REG);
			return -EINVAL;
		}
	}

	/*
	 * If ITE happens, all pending wait_desc commands are aborted.
	 * No new descriptors are fetched until the ITE is cleared.
	 */
	if (fault & DMA_FSTS_ITE) {
		head = readl(iommu->reg + DMAR_IQH_REG);
		head = ((head >> DMAR_IQ_SHIFT) - 1 + QI_LENGTH) % QI_LENGTH;
		head |= 1;
		tail = readl(iommu->reg + DMAR_IQT_REG);
		tail = ((tail >> DMAR_IQ_SHIFT) - 1 + QI_LENGTH) % QI_LENGTH;

		writel(DMA_FSTS_ITE, iommu->reg + DMAR_FSTS_REG);

		do {
			if (qi->desc_status[head] == QI_IN_USE)
				qi->desc_status[head] = QI_ABORT;
			head = (head - 2 + QI_LENGTH) % QI_LENGTH;
		} while (head != tail);

		if (qi->desc_status[wait_index] == QI_ABORT)
			return -EAGAIN;
	}

	if (fault & DMA_FSTS_ICE)
		writel(DMA_FSTS_ICE, iommu->reg + DMAR_FSTS_REG);

	return 0;
}

/*
 * Submit the queued invalidation descriptor to the remapping
 * hardware unit and wait for its completion.
 */
int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
{
	int rc;
	struct q_inval *qi = iommu->qi;
	struct qi_desc *hw, wait_desc;
	int wait_index, index;
	unsigned long flags;

	if (!qi)
		return 0;

	hw = qi->desc;

restart:
	rc = 0;

	raw_spin_lock_irqsave(&qi->q_lock, flags);
	while (qi->free_cnt < 3) {
		raw_spin_unlock_irqrestore(&qi->q_lock, flags);
		cpu_relax();
		raw_spin_lock_irqsave(&qi->q_lock, flags);
	}

	index = qi->free_head;
	wait_index = (index + 1) % QI_LENGTH;

	qi->desc_status[index] = qi->desc_status[wait_index] = QI_IN_USE;

	hw[index] = *desc;

	wait_desc.low = QI_IWD_STATUS_DATA(QI_DONE) |
			QI_IWD_STATUS_WRITE | QI_IWD_TYPE;
	wait_desc.high = virt_to_phys(&qi->desc_status[wait_index]);

	hw[wait_index] = wait_desc;

	__iommu_flush_cache(iommu, &hw[index], sizeof(struct qi_desc));
	__iommu_flush_cache(iommu, &hw[wait_index], sizeof(struct qi_desc));

	qi->free_head = (qi->free_head + 2) % QI_LENGTH;
	qi->free_cnt -= 2;

	/*
	 * update the HW tail register indicating the presence of
	 * new descriptors.
	 */
	writel(qi->free_head << DMAR_IQ_SHIFT, iommu->reg + DMAR_IQT_REG);

	while (qi->desc_status[wait_index] != QI_DONE) {
		/*
		 * We will leave the interrupts disabled, to prevent interrupt
		 * context to queue another cmd while a cmd is already submitted
		 * and waiting for completion on this cpu. This is to avoid
		 * a deadlock where the interrupt context can wait indefinitely
		 * for free slots in the queue.
		 */
		rc = qi_check_fault(iommu, index);
		if (rc)
			break;

		raw_spin_unlock(&qi->q_lock);
		cpu_relax();
		raw_spin_lock(&qi->q_lock);
	}

	qi->desc_status[index] = QI_DONE;

	reclaim_free_desc(qi);
	raw_spin_unlock_irqrestore(&qi->q_lock, flags);

	if (rc == -EAGAIN)
		goto restart;

	return rc;
}

/*
 * Flush the global interrupt entry cache.
 */
void qi_global_iec(struct intel_iommu *iommu)
{
	struct qi_desc desc;

	desc.low = QI_IEC_TYPE;
	desc.high = 0;

	/* should never fail */
	qi_submit_sync(&desc, iommu);
}

void qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
		      u64 type)
{
	struct qi_desc desc;

	desc.low = QI_CC_FM(fm) | QI_CC_SID(sid) | QI_CC_DID(did)
			| QI_CC_GRAN(type) | QI_CC_TYPE;
	desc.high = 0;

	qi_submit_sync(&desc, iommu);
}

void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
		    unsigned int size_order, u64 type)
{
	u8 dw = 0, dr = 0;

	struct qi_desc desc;
	int ih = 0;

	if (cap_write_drain(iommu->cap))
		dw = 1;

	if (cap_read_drain(iommu->cap))
		dr = 1;

	desc.low = QI_IOTLB_DID(did) | QI_IOTLB_DR(dr) | QI_IOTLB_DW(dw)
		| QI_IOTLB_GRAN(type) | QI_IOTLB_TYPE;
	desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih)
		| QI_IOTLB_AM(size_order);

	qi_submit_sync(&desc, iommu);
}

void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 qdep,
			u64 addr, unsigned mask)
{
	struct qi_desc desc;

	if (mask) {
		BUG_ON(addr & ((1 << (VTD_PAGE_SHIFT + mask)) - 1));
		addr |= (1 << (VTD_PAGE_SHIFT + mask - 1)) - 1;
		desc.high = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE;
	} else
		desc.high = QI_DEV_IOTLB_ADDR(addr);

	if (qdep >= QI_DEV_IOTLB_MAX_INVS)
		qdep = 0;

	desc.low = QI_DEV_IOTLB_SID(sid) | QI_DEV_IOTLB_QDEP(qdep) |
		   QI_DIOTLB_TYPE;

	qi_submit_sync(&desc, iommu);
}

/*
 * Disable Queued Invalidation interface.
 */
void dmar_disable_qi(struct intel_iommu *iommu)
{
	unsigned long flags;
	u32 sts;
	cycles_t start_time = get_cycles();

	if (!ecap_qis(iommu->ecap))
		return;

	raw_spin_lock_irqsave(&iommu->register_lock, flags);

	sts =  readl(iommu->reg + DMAR_GSTS_REG);
	if (!(sts & DMA_GSTS_QIES))
		goto end;

	/*
	 * Give a chance to HW to complete the pending invalidation requests.
	 */
	while ((readl(iommu->reg + DMAR_IQT_REG) !=
		readl(iommu->reg + DMAR_IQH_REG)) &&
		(DMAR_OPERATION_TIMEOUT > (get_cycles() - start_time)))
		cpu_relax();

	iommu->gcmd &= ~DMA_GCMD_QIE;
	writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);

	IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl,
		      !(sts & DMA_GSTS_QIES), sts);
end:
	raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
}

/*
 * Enable queued invalidation.
 */
static void __dmar_enable_qi(struct intel_iommu *iommu)
{
	u32 sts;
	unsigned long flags;
	struct q_inval *qi = iommu->qi;

	qi->free_head = qi->free_tail = 0;
	qi->free_cnt = QI_LENGTH;

	raw_spin_lock_irqsave(&iommu->register_lock, flags);

	/* write zero to the tail reg */
	writel(0, iommu->reg + DMAR_IQT_REG);

	dmar_writeq(iommu->reg + DMAR_IQA_REG, virt_to_phys(qi->desc));

	iommu->gcmd |= DMA_GCMD_QIE;
	writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);

	/* Make sure hardware complete it */
	IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_QIES), sts);

	raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
}

/*
 * Enable Queued Invalidation interface. This is a must to support
 * interrupt-remapping. Also used by DMA-remapping, which replaces
 * register based IOTLB invalidation.
 */
int dmar_enable_qi(struct intel_iommu *iommu)
{
	struct q_inval *qi;
	struct page *desc_page;

	if (!ecap_qis(iommu->ecap))
		return -ENOENT;

	/*
	 * queued invalidation is already setup and enabled.
	 */
	if (iommu->qi)
		return 0;

	iommu->qi = kmalloc(sizeof(*qi), GFP_ATOMIC);
	if (!iommu->qi)
		return -ENOMEM;

	qi = iommu->qi;

	desc_page = alloc_pages_node(iommu->node, GFP_ATOMIC | __GFP_ZERO, 0);
	if (!desc_page) {
		kfree(qi);
		iommu->qi = NULL;
		return -ENOMEM;
	}

	qi->desc = page_address(desc_page);

	qi->desc_status = kzalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC);
	if (!qi->desc_status) {
		free_page((unsigned long) qi->desc);
		kfree(qi);
		iommu->qi = NULL;
		return -ENOMEM;
	}

	raw_spin_lock_init(&qi->q_lock);

	__dmar_enable_qi(iommu);

	return 0;
}

/* iommu interrupt handling. Most stuff are MSI-like. */

enum faulttype {
	DMA_REMAP,
	INTR_REMAP,
	UNKNOWN,
};

static const char *dma_remap_fault_reasons[] =
{
	"Software",
	"Present bit in root entry is clear",
	"Present bit in context entry is clear",
	"Invalid context entry",
	"Access beyond MGAW",
	"PTE Write access is not set",
	"PTE Read access is not set",
	"Next page table ptr is invalid",
	"Root table address invalid",
	"Context table ptr is invalid",
	"non-zero reserved fields in RTP",
	"non-zero reserved fields in CTP",
	"non-zero reserved fields in PTE",
	"PCE for translation request specifies blocking",
};

static const char *irq_remap_fault_reasons[] =
{
	"Detected reserved fields in the decoded interrupt-remapped request",
	"Interrupt index exceeded the interrupt-remapping table size",
	"Present field in the IRTE entry is clear",
	"Error accessing interrupt-remapping table pointed by IRTA_REG",
	"Detected reserved fields in the IRTE entry",
	"Blocked a compatibility format interrupt request",
	"Blocked an interrupt request due to source-id verification failure",
};

static const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
{
	if (fault_reason >= 0x20 && (fault_reason - 0x20 <
					ARRAY_SIZE(irq_remap_fault_reasons))) {
		*fault_type = INTR_REMAP;
		return irq_remap_fault_reasons[fault_reason - 0x20];
	} else if (fault_reason < ARRAY_SIZE(dma_remap_fault_reasons)) {
		*fault_type = DMA_REMAP;
		return dma_remap_fault_reasons[fault_reason];
	} else {
		*fault_type = UNKNOWN;
		return "Unknown";
	}
}

static inline int dmar_msi_reg(struct intel_iommu *iommu, int irq)
{
	if (iommu->irq == irq)
		return DMAR_FECTL_REG;
	else if (iommu->pr_irq == irq)
		return DMAR_PECTL_REG;
	else
		BUG();
}

void dmar_msi_unmask(struct irq_data *data)
{
	struct intel_iommu *iommu = irq_data_get_irq_handler_data(data);
	int reg = dmar_msi_reg(iommu, data->irq);
	unsigned long flag;

	/* unmask it */
	raw_spin_lock_irqsave(&iommu->register_lock, flag);
	writel(0, iommu->reg + reg);
	/* Read a reg to force flush the post write */
	readl(iommu->reg + reg);
	raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
}

void dmar_msi_mask(struct irq_data *data)
{
	struct intel_iommu *iommu = irq_data_get_irq_handler_data(data);
	int reg = dmar_msi_reg(iommu, data->irq);
	unsigned long flag;

	/* mask it */
	raw_spin_lock_irqsave(&iommu->register_lock, flag);
	writel(DMA_FECTL_IM, iommu->reg + reg);
	/* Read a reg to force flush the post write */
	readl(iommu->reg + reg);
	raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
}

void dmar_msi_write(int irq, struct msi_msg *msg)
{
	struct intel_iommu *iommu = irq_get_handler_data(irq);
	int reg = dmar_msi_reg(iommu, irq);
	unsigned long flag;

	raw_spin_lock_irqsave(&iommu->register_lock, flag);
	writel(msg->data, iommu->reg + reg + 4);
	writel(msg->address_lo, iommu->reg + reg + 8);
	writel(msg->address_hi, iommu->reg + reg + 12);
	raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
}

void dmar_msi_read(int irq, struct msi_msg *msg)
{
	struct intel_iommu *iommu = irq_get_handler_data(irq);
	int reg = dmar_msi_reg(iommu, irq);
	unsigned long flag;

	raw_spin_lock_irqsave(&iommu->register_lock, flag);
	msg->data = readl(iommu->reg + reg + 4);
	msg->address_lo = readl(iommu->reg + reg + 8);
	msg->address_hi = readl(iommu->reg + reg + 12);
	raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
}

static int dmar_fault_do_one(struct intel_iommu *iommu, int type,
		u8 fault_reason, u16 source_id, unsigned long long addr)
{
	const char *reason;
	int fault_type;

	reason = dmar_get_fault_reason(fault_reason, &fault_type);

	if (fault_type == INTR_REMAP)
		pr_err("[INTR-REMAP] Request device [%02x:%02x.%d] fault index %llx [fault reason %02d] %s\n",
			source_id >> 8, PCI_SLOT(source_id & 0xFF),
			PCI_FUNC(source_id & 0xFF), addr >> 48,
			fault_reason, reason);
	else
		pr_err("[%s] Request device [%02x:%02x.%d] fault addr %llx [fault reason %02d] %s\n",
		       type ? "DMA Read" : "DMA Write",
		       source_id >> 8, PCI_SLOT(source_id & 0xFF),
		       PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
	return 0;
}

#define PRIMARY_FAULT_REG_LEN (16)
irqreturn_t dmar_fault(int irq, void *dev_id)
{
	struct intel_iommu *iommu = dev_id;
	int reg, fault_index;
	u32 fault_status;
	unsigned long flag;
	bool ratelimited;
	static DEFINE_RATELIMIT_STATE(rs,
				      DEFAULT_RATELIMIT_INTERVAL,
				      DEFAULT_RATELIMIT_BURST);

	/* Disable printing, simply clear the fault when ratelimited */
	ratelimited = !__ratelimit(&rs);

	raw_spin_lock_irqsave(&iommu->register_lock, flag);
	fault_status = readl(iommu->reg + DMAR_FSTS_REG);
	if (fault_status && !ratelimited)
		pr_err("DRHD: handling fault status reg %x\n", fault_status);

	/* TBD: ignore advanced fault log currently */
	if (!(fault_status & DMA_FSTS_PPF))
		goto unlock_exit;

	fault_index = dma_fsts_fault_record_index(fault_status);
	reg = cap_fault_reg_offset(iommu->cap);
	while (1) {
		u8 fault_reason;
		u16 source_id;
		u64 guest_addr;
		int type;
		u32 data;

		/* highest 32 bits */
		data = readl(iommu->reg + reg +
				fault_index * PRIMARY_FAULT_REG_LEN + 12);
		if (!(data & DMA_FRCD_F))
			break;

		if (!ratelimited) {
			fault_reason = dma_frcd_fault_reason(data);
			type = dma_frcd_type(data);

			data = readl(iommu->reg + reg +
				     fault_index * PRIMARY_FAULT_REG_LEN + 8);
			source_id = dma_frcd_source_id(data);

			guest_addr = dmar_readq(iommu->reg + reg +
					fault_index * PRIMARY_FAULT_REG_LEN);
			guest_addr = dma_frcd_page_addr(guest_addr);
		}

		/* clear the fault */
		writel(DMA_FRCD_F, iommu->reg + reg +
			fault_index * PRIMARY_FAULT_REG_LEN + 12);

		raw_spin_unlock_irqrestore(&iommu->register_lock, flag);

		if (!ratelimited)
			dmar_fault_do_one(iommu, type, fault_reason,
					  source_id, guest_addr);

		fault_index++;
		if (fault_index >= cap_num_fault_regs(iommu->cap))
			fault_index = 0;
		raw_spin_lock_irqsave(&iommu->register_lock, flag);
	}

	writel(DMA_FSTS_PFO | DMA_FSTS_PPF, iommu->reg + DMAR_FSTS_REG);

unlock_exit:
	raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
	return IRQ_HANDLED;
}

int dmar_set_interrupt(struct intel_iommu *iommu)
{
	int irq, ret;

	/*
	 * Check if the fault interrupt is already initialized.
	 */
	if (iommu->irq)
		return 0;

	irq = dmar_alloc_hwirq(iommu->seq_id, iommu->node, iommu);
	if (irq > 0) {
		iommu->irq = irq;
	} else {
		pr_err("No free IRQ vectors\n");
		return -EINVAL;
	}

	ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu);
	if (ret)
		pr_err("Can't request irq\n");
	return ret;
}

int __init enable_drhd_fault_handling(void)
{
	struct dmar_drhd_unit *drhd;
	struct intel_iommu *iommu;

	/*
	 * Enable fault control interrupt.
	 */
	for_each_iommu(iommu, drhd) {
		u32 fault_status;
		int ret = dmar_set_interrupt(iommu);

		if (ret) {
			pr_err("DRHD %Lx: failed to enable fault, interrupt, ret %d\n",
			       (unsigned long long)drhd->reg_base_addr, ret);
			return -1;
		}

		/*
		 * Clear any previous faults.
		 */
		dmar_fault(iommu->irq, iommu);
		fault_status = readl(iommu->reg + DMAR_FSTS_REG);
		writel(fault_status, iommu->reg + DMAR_FSTS_REG);
	}

	return 0;
}

/*
 * Re-enable Queued Invalidation interface.
 */
int dmar_reenable_qi(struct intel_iommu *iommu)
{
	if (!ecap_qis(iommu->ecap))
		return -ENOENT;

	if (!iommu->qi)
		return -ENOENT;

	/*
	 * First disable queued invalidation.
	 */
	dmar_disable_qi(iommu);
	/*
	 * Then enable queued invalidation again. Since there is no pending
	 * invalidation requests now, it's safe to re-enable queued
	 * invalidation.
	 */
	__dmar_enable_qi(iommu);

	return 0;
}

/*
 * Check interrupt remapping support in DMAR table description.
 */
int __init dmar_ir_support(void)
{
	struct acpi_table_dmar *dmar;
	dmar = (struct acpi_table_dmar *)dmar_tbl;
	if (!dmar)
		return 0;
	return dmar->flags & 0x1;
}

/* Check whether DMAR units are in use */
static inline bool dmar_in_use(void)
{
	return irq_remapping_enabled || intel_iommu_enabled;
}

static int __init dmar_free_unused_resources(void)
{
	struct dmar_drhd_unit *dmaru, *dmaru_n;

	if (dmar_in_use())
		return 0;

	if (dmar_dev_scope_status != 1 && !list_empty(&dmar_drhd_units))
		bus_unregister_notifier(&pci_bus_type, &dmar_pci_bus_nb);

	down_write(&dmar_global_lock);
	list_for_each_entry_safe(dmaru, dmaru_n, &dmar_drhd_units, list) {
		list_del(&dmaru->list);
		dmar_free_drhd(dmaru);
	}
	up_write(&dmar_global_lock);

	return 0;
}

late_initcall(dmar_free_unused_resources);
IOMMU_INIT_POST(detect_intel_iommu);

/*
 * DMAR Hotplug Support
 * For more details, please refer to Intel(R) Virtualization Technology
 * for Directed-IO Architecture Specifiction, Rev 2.2, Section 8.8
 * "Remapping Hardware Unit Hot Plug".
 */
static u8 dmar_hp_uuid[] = {
	/* 0000 */    0xA6, 0xA3, 0xC1, 0xD8, 0x9B, 0xBE, 0x9B, 0x4C,
	/* 0008 */    0x91, 0xBF, 0xC3, 0xCB, 0x81, 0xFC, 0x5D, 0xAF
};

/*
 * Currently there's only one revision and BIOS will not check the revision id,
 * so use 0 for safety.
 */
#define	DMAR_DSM_REV_ID			0
#define	DMAR_DSM_FUNC_DRHD		1
#define	DMAR_DSM_FUNC_ATSR		2
#define	DMAR_DSM_FUNC_RHSA		3

static inline bool dmar_detect_dsm(acpi_handle handle, int func)
{
	return acpi_check_dsm(handle, dmar_hp_uuid, DMAR_DSM_REV_ID, 1 << func);
}

static int dmar_walk_dsm_resource(acpi_handle handle, int func,
				  dmar_res_handler_t handler, void *arg)
{
	int ret = -ENODEV;
	union acpi_object *obj;
	struct acpi_dmar_header *start;
	struct dmar_res_callback callback;
	static int res_type[] = {
		[DMAR_DSM_FUNC_DRHD] = ACPI_DMAR_TYPE_HARDWARE_UNIT,
		[DMAR_DSM_FUNC_ATSR] = ACPI_DMAR_TYPE_ROOT_ATS,
		[DMAR_DSM_FUNC_RHSA] = ACPI_DMAR_TYPE_HARDWARE_AFFINITY,
	};

	if (!dmar_detect_dsm(handle, func))
		return 0;

	obj = acpi_evaluate_dsm_typed(handle, dmar_hp_uuid, DMAR_DSM_REV_ID,
				      func, NULL, ACPI_TYPE_BUFFER);
	if (!obj)
		return -ENODEV;

	memset(&callback, 0, sizeof(callback));
	callback.cb[res_type[func]] = handler;
	callback.arg[res_type[func]] = arg;
	start = (struct acpi_dmar_header *)obj->buffer.pointer;
	ret = dmar_walk_remapping_entries(start, obj->buffer.length, &callback);

	ACPI_FREE(obj);

	return ret;
}

static int dmar_hp_add_drhd(struct acpi_dmar_header *header, void *arg)
{
	int ret;
	struct dmar_drhd_unit *dmaru;

	dmaru = dmar_find_dmaru((struct acpi_dmar_hardware_unit *)header);
	if (!dmaru)
		return -ENODEV;

	ret = dmar_ir_hotplug(dmaru, true);
	if (ret == 0)
		ret = dmar_iommu_hotplug(dmaru, true);

	return ret;
}

static int dmar_hp_remove_drhd(struct acpi_dmar_header *header, void *arg)
{
	int i, ret;
	struct device *dev;
	struct dmar_drhd_unit *dmaru;

	dmaru = dmar_find_dmaru((struct acpi_dmar_hardware_unit *)header);
	if (!dmaru)
		return 0;

	/*
	 * All PCI devices managed by this unit should have been destroyed.
	 */
	if (!dmaru->include_all && dmaru->devices && dmaru->devices_cnt)
		for_each_active_dev_scope(dmaru->devices,
					  dmaru->devices_cnt, i, dev)
			return -EBUSY;

	ret = dmar_ir_hotplug(dmaru, false);
	if (ret == 0)
		ret = dmar_iommu_hotplug(dmaru, false);

	return ret;
}

static int dmar_hp_release_drhd(struct acpi_dmar_header *header, void *arg)
{
	struct dmar_drhd_unit *dmaru;

	dmaru = dmar_find_dmaru((struct acpi_dmar_hardware_unit *)header);
	if (dmaru) {
		list_del_rcu(&dmaru->list);
		synchronize_rcu();
		dmar_free_drhd(dmaru);
	}

	return 0;
}

static int dmar_hotplug_insert(acpi_handle handle)
{
	int ret;
	int drhd_count = 0;

	ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD,
				     &dmar_validate_one_drhd, (void *)1);
	if (ret)
		goto out;

	ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD,
				     &dmar_parse_one_drhd, (void *)&drhd_count);
	if (ret == 0 && drhd_count == 0) {
		pr_warn(FW_BUG "No DRHD structures in buffer returned by _DSM method\n");
		goto out;
	} else if (ret) {
		goto release_drhd;
	}

	ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_RHSA,
				     &dmar_parse_one_rhsa, NULL);
	if (ret)
		goto release_drhd;

	ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_ATSR,
				     &dmar_parse_one_atsr, NULL);
	if (ret)
		goto release_atsr;

	ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD,
				     &dmar_hp_add_drhd, NULL);
	if (!ret)
		return 0;

	dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD,
			       &dmar_hp_remove_drhd, NULL);
release_atsr:
	dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_ATSR,
			       &dmar_release_one_atsr, NULL);
release_drhd:
	dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD,
			       &dmar_hp_release_drhd, NULL);
out:
	return ret;
}

static int dmar_hotplug_remove(acpi_handle handle)
{
	int ret;

	ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_ATSR,
				     &dmar_check_one_atsr, NULL);
	if (ret)
		return ret;

	ret = dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD,
				     &dmar_hp_remove_drhd, NULL);
	if (ret == 0) {
		WARN_ON(dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_ATSR,
					       &dmar_release_one_atsr, NULL));
		WARN_ON(dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD,
					       &dmar_hp_release_drhd, NULL));
	} else {
		dmar_walk_dsm_resource(handle, DMAR_DSM_FUNC_DRHD,
				       &dmar_hp_add_drhd, NULL);
	}

	return ret;
}

static acpi_status dmar_get_dsm_handle(acpi_handle handle, u32 lvl,
				       void *context, void **retval)
{
	acpi_handle *phdl = retval;

	if (dmar_detect_dsm(handle, DMAR_DSM_FUNC_DRHD)) {
		*phdl = handle;
		return AE_CTRL_TERMINATE;
	}

	return AE_OK;
}

static int dmar_device_hotplug(acpi_handle handle, bool insert)
{
	int ret;
	acpi_handle tmp = NULL;
	acpi_status status;

	if (!dmar_in_use())
		return 0;

	if (dmar_detect_dsm(handle, DMAR_DSM_FUNC_DRHD)) {
		tmp = handle;
	} else {
		status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
					     ACPI_UINT32_MAX,
					     dmar_get_dsm_handle,
					     NULL, NULL, &tmp);
		if (ACPI_FAILURE(status)) {
			pr_warn("Failed to locate _DSM method.\n");
			return -ENXIO;
		}
	}
	if (tmp == NULL)
		return 0;

	down_write(&dmar_global_lock);
	if (insert)
		ret = dmar_hotplug_insert(tmp);
	else
		ret = dmar_hotplug_remove(tmp);
	up_write(&dmar_global_lock);

	return ret;
}

int dmar_device_add(acpi_handle handle)
{
	return dmar_device_hotplug(handle, true);
}

int dmar_device_remove(acpi_handle handle)
{
	return dmar_device_hotplug(handle, false);
}

redpajama_set_name: RedPajamaGithub


text:
External release_Walki acquires Meuwissen.pdf
walki.com
Meuwissen,
Walki,
Thissen,
Laminates,
Announced,
Acquires
3 October 2011Walki Group buys Meuwissen and strengthens its leadingposition in multi-layer laminatesWalki Group, a leading producer of technical laminates and protective packaging materials,today announced the completion of the acquisition of Meuwissen Industrie B.V., a producer offlexible packaging materials, and Meuwissen Bouwprodukten B.V., a specialist distributor ofbuilding and construction materials. Both businesses are located in The Netherlands,employing 65 persons in total, with net sales of 21 million Euros in 2010."The acquisition of Meuwissen is an important step for Walki as it will allow us to furtherdevelop our position as a leading producer of technical laminates and protective packagingmaterials", commented Leif Frilund, President and CEO of Walki Group. "Their location in theNetherlands is an excellent fit to Walki's existing plant network and they will increase our localcoverage in the important central European markets".Walki Group has announced that the Meuwissen businesses will be integrated into theirTechnical Products business area, which currently has production in Finland, Germany,Sweden, the UK and China."The knowledge, technical capability and flexible way of working at Meuwissen fits perfectlywith Walki and together we will continue to offer the creative solutions that bring the value ourcustomers expect from us", says Wolfgang Thissen, Vice President and General Manager ofthe Technical Products business area. "Additionally, their network of distribution channels willprovide enhanced access to markets in Central Europe for the combined business, bringingbenefits for the whole supply chain".Jan Gerritsen, owner of Meuwissen Group, confirmed "I am convinced that Meuwissen has agood business platform which can be further developed with Walki's knowledge andexpertise, and will become an important contributor to the future success of the Walki Group.We are pleased to be part of this exciting new development".Wolfgang Thissen, Vice President and General Manager Technical Products will beappointed Managing Director of the acquired entities in addition to his present duties and hewill be located in Haarlem.Walki Group, owned by Nordic private equity investor CapMan and the company'smanagement, acquired Meuwissen Industrie B.V. and Meuwissen Bouwprodukten B.V. fromMeuwissen Holding B.V. The parties have agreed not to disclose the acquisition price.For further information, please contact:Leif Frilund, President and CEO, Walki GroupTel: +358(0)40 354 3330Wolfgang Thissen, Vice President and General Manager Technical ProductsTel: +49 (0) 173 576 3804
Walki in briefWalki Group is a leading producer of technical laminates and protective packaging materials,specialising in the production of fibre based, intelligent, multilaminate products for markets asdiverse as energy saving construction facings to barrier packaging applications. Walki Grouphas operations in Finland, Sweden, Germany, Poland, the UK, Russia and China with aworkforce of approx. 1,000 people. Annual net sales for the Group are 300 million Euros.www.walki.comMeuwissen in briefMeuwissen is an independent, family owned company, founded in 1954. The companyspecialise in the manufacture of products for the construction, building and industrialpackaging markets; adding value to their customers business by improving performance andhelping to reduce the total cost of ownership, where Meuwissen products are used. Thecompany employ 65 people from their base in Haarlem, The Netherlands. Annual net salesfor the company are 21 million Euros.www.meuwissen-industrie.com
Page 2: Walki in briefWalki Group is a lead
Magazine: External release_Walki acquires Meuwissen.pdf

redpajama_set_name: RedPajamaCommonCrawl


View current news clips below featuring UPMC Children's Hospital of Pittsburgh's patients, programs, staff, and much more. Please check back often for continued updates.
What's Driving the Rise in Type 2 Diabetes in Kids?
How big of an issue is vaping in local schools?
Can Delaying School Start Times Benefit Students?
Can Vaping Cause Serious Lung Disorders?
How Long Do Sippy Cups Last?
Who is the next Larry Nassar?
How to help children with asthma?
Big recognition: Pittsburgh's Children's Hospital named among top pediatrics hospitals in U.S.
Keisel's Annual Shear Da Beard!
Free Care Fund Telethon Airs Tonight On KDKA-TV!
Who Are Pittsburgh's Young Philanthropists?
The Children's Trust celebrates one year!
It's Known that Lead Causes Cognitive Deficits, but How?
Pokémon Go players getting into car accidents across U.S.
I Survived Childhood Cancer, Now What?
Does The Internet Fail Teens Needing Health Information?


I have been experiencing some pale yellow discharge over the last week or so. I mentioned it to my doc and she just said "it could be normal". Is anyone else experiencing this? My google searches give mixed results but there is no odor, it's only yellow when it dries on my liner otherwise looks normal, and no itching or burning either. I didn't have this with my first so it's new to me this pregnancy. I've had a urine analysis done, not specifically because of this as it was a few weeks ago, but doc said everything looked normal.
It could be vaginosis but they won't test you for it until after you've had birth. It won't hurt the baby. It could also be nothing/hormone related.
I agree with GabrielaD25. My prenatal vitamins made my urine colour bright yellow, making my discharge light yellow. It doesnt have a bad smell nor I have any itching down there.
I'm 11w and having this as well. I asked my doctor about it over the phone and she said vaginal discharge can be any color that nasal discharge could be. She said if it's smells really strong like fish, she'd be worried about a bacterial infection. I don't think mine is "fishy" smelling but it's definitely yellow-ish. I have an appointment on Monday so I'll ask her more in detail!
I've had it since the beginning of the pregnancy. I'm in agreement with other ladies: as long as there's no odor, it is most likely just caused by your prenatals.
I experienced yellow discharge. I went to my ob and the culture cams back normal.
Not true. I was just tested for vaginosis. All they do is take a sample of the vaginal discharge and look at with a microscope. I don't see why that wouldn't be done until after birth. Please be careful not to share misinformation.
Umbilical Cord Care for Your Newborn | What to Expect Caring for baby's umbilical cord after birth is simpler than it might seem. Here's what you need to know from What To Expect.


Mozzarella, provolone, home made guacamole & Pico de Gallo, sour cream.
Fried egg roll with grated cheese, black bean, corn, and choice of chicken or chorizo.
House made flatbread topped with garlic topping. Served with marinara for dipping.
House made guacamole with tortilla chips.
Hot, Sweet BBQ, Mambo or dry Old Bay chicken wings served with blue cheese or ranch dressing.
Three all-beef sliders, tomato, grilled onion, mixed greens, cheddar cheese, herbed mayonnaise. Served on a slider roll with Dijon mustard and our horseradish mayonnaise for dipping.
A confetti of asparagus, oranges, strawberries and mixed peppers served over baby field green with rasberry vinaigrette.
Baby lettuce, blue cheese crumbles, sunflower seeds, blanched potatoes and marinated mushrooms with your choice of dressing.
Mixed greens, Hanger Steak, grilled onions, bell peppers and sun-dried tomatoes. Herbed balsamic vinegar and oil.
Mixed greens, edamame, quinoa, diced tomatoes, olives, wasabi peas and feta cheese. Served with our sesame-siracha vinaigrette.
Grilled Chicken breast on a bed of mixed greens tossed with chopped apple and celery, red grapes and pecans. Mixed with Fat-free yogurt and honey dressing.
Spinach salad with polenta, fresh mozzarella, caramelized pearl onions and toasted almonds with your choice of dressing.
Thick sliced tomato, mozzarella, roasted sweet red peppers and asparagus all layered onto baby greens with your choice of dressing.
Sliced granny smith apples, fresh mozzarella, toasted pecans with mixed greens and honey mustard vinaigrette.
Romaine lettuce, onion, cucumber, couscous, hearts of palm, grilled eggplant and lemon and oil dressing.
Arugula, prosciutto, fig, house made croutons, black olives, goat cheese and balsamic vinaigrette.
Sandwiches come with side of house cut fries, sweet potato fries, or side salad. Bread choices: 3-grain wheat, ciabatta, baguette, spinach tortilla wrap.
6 oz. cut teres major, mescaline lettuce, grilled onions, herbed mayonnaise.
Homemade pork shoulder BBQ and coleslaw, lightly toasted brioche bun.
Ham, turkey, lettuce, tomato, onion, spicy honey mustard, and bacon on sourdough.
Grilled Portobello, carmelized onion, roasted pepper, shaved parmesan and spinach, on 3-grain wheat bread.
Grilled chicken breast, chopped arugula, roasted red-peppers, pesto and a drizzle of balsamic vinaigrette on toasted ciabatta.
Grilled eggplant, zucchini, tomato, roasted red-pepper, baby spinach and an herbed mayonnaise on your choice of bread.
Grilled chicken breast with granny smith apples sliced julienne, melted mozzarella, baby spinach and balsamic vinaigrette in a spinach tortilla wrap.
Thinly sliced prosciutto, sliced figs, arugula, and grated fontina cheese on toasted ciabatta, served with honey mustard.
Sweet Italian sausage, grilled onions, red, green, and yellow peppers, served in an Italian loaf.
Bison Burger with sharp cheddar cheese, lettuce, tomato and onion, served on an onion brioche bun.
Spice it up with the ghost pepper cheddar for $0.50!
Combine any one soup with a grilled cheese.
Pulled pork, jalepenos, mozzarella, pineapple, and a BBQ sauce base.
Chorizo, jalapenos, mozzarella, onions, topped with hot sauce and blue cheese crumbles.
Fresh mozzarella, tomato sauce, olive oil.
Hand cut salami and sausage, sun dried tomato, spicy pepper, fresh mozzarella, tomato sauce.
Grilled chicken, fresh mozzarella, mushrooms, sliced tomatoes, green peppers, on top of a ranch dressing base.
Hand cut pepperoni, spinach, black olives, tomato sauce, fresh mozzarella and a sprinkle of feta cheese.
Roasted eggplant, broccolini, fresh mozzarella, tomato sauce, topped with goat cheese.
Prosciutto, arugula, candied figs, fresh mozzarella and tomato sauce.
White Pizza - fresh mozzarella, fontina, ricotta, and parmesan cheeses.
Bacon, pineapple, fresh mozzarella, tomato sauce.
Deep Eddy All Natural Lemon Vodka, Fresh Strawberry, and Soda. A True Summer Treat!
Vodka, Grape Juice, and Ginger Ale. Join the club!
Stoli Blu', Peach Schnapps, Juices, Pink.
44 North Huckleberry Vodka Mixed with Becky's Pink Lemonade. Specialty Mason Jar.
Corralejo Tequila, Agave Nectar and a Squeeze of Fresh Lime. Real Simple 'Rita.
Crabbie's Ginger Beer, Goslings Rum. Our own special Dark and Stormy!
Hendrick's Gin with Cucumber and a Splash of Club Soda.
Bloody Mary with Moose Mix Hand-Made Bloody Mary Mix & Hanger One Chipotle Vodka.
Served until 4pm. Each Brunch Entree is Served with Your Choice of Side. Choose from Fresh Mixed Fruit, Brunch Potatoes, Fries, Sweet Potato Fries, Side Salad, or Pasta Salad.
Scrambled Eggs, Applewood Bacon, Free Range Bison, Sharp Cheddar Cheese, Mixed Bell Peppers, and our House Made Chipotle Sauce, served in an Herb Wrap.
Scrambled Eggs, Roasted Red Peppers, Tomatoes, Onions, Baby Spinach, Shaved Parmesan and Pesto, served in a Tomato Wrap.
Scrambled Eggs, Italian Sausage, Diced Salami and Pepperoni, Fresh Basil, and Shaved Parmesan, served in an Herb Wrap.
Scrambled Eggs, Black Beans, Sliced Tomatoes, and Diced Sausage, served in a Wheat Wrap. This one has no cheese or sauce!
Scrambled Eggs, Spicy Chorizo, Pico de Gallo, Cous Cous, Mozzarella, and our House Made Chipotle Sauce, served in a Jalapeno Wrap.
Our make it your own brunch platter. Start with scrambled eggs, and custimize it with the following options! Add any combination of onions, peppers, tomatoes, and cheddar to your eggs. Served with your choice of breakfast meat (bacon or sausage), side, and toast (wheat or baguette).


In the October 1909 issue of American Homes and Gardens Poultney Bigelow wrote, "Ralph Whitehead is a mighty farmer in addition to his other many accomplishments." While not a "mighty farmer" Whitehead did, however, have "mighty" barns as he intended that farming be apart of his utopian community from its inception. The double barn was designed by Whitehead and Bolton Brown and built by local carpenters, probably Fordyce Herrick, to include multiple levels and measure in at 6,200 square feet. According to architectural historian Cheryl Robertson barns such as these were "the most potent emblem of landed aristocracy" as photographs show Whitehead could gaze from the porch of White Pines to see his barns that were reminiscent of the farms of his English upbringing. Indeed, Whitehead was enamored with the medieval influences of the Arts and Crafts movement and equipped his barn with a dovecote, a sign of prestige for an English lord of the manor and a cupola, a sign of wealth and status for American aristocrats.
The farming was undertaken by Carl Eric Lindin and Hervey White took charge of the milk, butter, and cream allotment from the colony's thirty cows. In the upper level of the barn, marked with the cupola, housed the hay making enterprise while the lower barn held the creamery. The complex largely supplied the community with milk, eggs, vegetables, and grain until Whitehead died in 1929.
Thomas A. Guiler, "The Barns," UpstateHistorical, accessed April 18, 2019, http://upstatehistorical.org/items/show/3.
Poultney Bigelow, "The Byrdcliffe Colony of Arts and Crafts," American Homes and Gardens 6 (October 1909).Evers, Alf. The Catskills: From Wilderness to Woodstock. Garden City, NY: Doubleday & Company, Inc., 1972.Evers, Alf. Woodstock: History of an American Town (Woodstock, NY: Overlook Press, 1987.Robertson, Cheryl. "Nature and Artifice in the Architecture of Byrdcliffe," in Byrdcliffe: An American Arts and Crafts Colony Nancy Green ed. Ithaca, NY: Herbert F. Johnson Museum of Art, 2004. Smith, A. M. Woodstock: History and Hearsay. Woodstock, N.Y.: Woodstock Arts, 2006.


As your family hunts for their new home, be sure you are looking in all of the right places. The homes for sale Chesapeake VA has to offer will blow you away with their quality, beauty and family atmosphere. Do not make the task of home buying any harder on yourself than it has to be. These spaces are going to go quickly. Right now there are homes for sale Chesapeake VA locals say cannot be beat. If you and your family are seeking quality, safety and beauty, it is time to stop your search in Chesapeake VA.
Moving can be discouraging. Yet, if you are looking in the right places it could be an extremely rewarding experience that you just may wish you had done earlier. The homes for sale chesapeake va has to offer could change the way you feel about home buying for good.


text:
Egypt international Ramadan Sobhi joins Huddersfield Town
2:57 PM EDT 6/12/18
The 21-year-old will stay in the Premier League after spending two seasons with Stoke City
Ramadan Sobhi has completed a £5.7 million move to Huddersfield Town after spending two seasons with Stoke City.
Sobhi joins on a three-year deal, staying in the Premier League after Stoke were relegated to the Championship following the 2017-18 season.
The Egypt international made 41 Premier League appearances with the Potters after joining from Al Ahly in July 2016, scoring two goals.
The midfielder was allowed to leave Egypt camp in Russia and fly to England to undergo a medical with the Terriers.
"I'm very happy that we will be able to welcome Ramadan to the club. He's a real talent and has achieved a lot for a player who is only 21 years old," Huddersfield boss David Wagner said in a club release.
"We're looking forward to working hard with Ramadan on the training pitch to give him every chance of success at Huddersfield Town."
Sobhi has been capped 26 times by Egypt, and is set to play a significant role in his country's first World Cup since 1990.
Egypt's first match will be Friday against Uruguay, with the Pharaohs then set to face Russia and Saudi Arabia in Group A.
Copyright © 2023 Goal (United States) All rights reserved. The information contained in Goal (United States) may not be published, broadcast, rewritten, or redistributed without the prior written authority of Goal (United States)


text:
Q: Palabras "reservadas" de PHP que no puedo usar Estoy armándome un script en PHP que lo que hace es generar el texto que va dentro de un archivo .php, desde allí recorro tabla y demás cosas, pero cuando quiero usar la palabra, por ejemplo, $_POST[], me genera un error, ¿cómo tengo que poner $_POST[] para que me lo escriba y muestre en pantalla? ¿de qué forma puedo "enmascarar" este tipo de palabra como para que en la pantalla me muestre la palabra correcta?
Paso un ejemplo:
$script_php .= "# Generamos la sección de grabación después del POST :".$enter;

$script_php .= "if(isset($_POST['btn_grabar']))".$enter;

$script_php .= "{".$enter;

$script_php .= "$".$primary_key." = $SESSION['".$primary_key."']".$enter;

Lo que quiero es visualizar algo así como :
if(isset($_POST['btn_grabar']))

    $id_hipodromo = $_SESSION['id_'];

    $id_animal=$_POST['id_animal'];
    $nombre=$_POST['nombre'];

A: Cuando usas cadenas de caracteres delimitadas por comillas dobles (") estás permitiendo la interpretación de variables en su interior, por eso trata de convertir $_POST por su valor.
De modo que el problema no es el uso de "palabras reservadas" en una cadena de caracteres, si no el uso de variables dentro de ellas cuando se usan comillas dobles o heredoc.
Para evitar que las variables se interpreten dentro de cadenas de caracteres tienes dos opciones:
Comillas sencillas (')
$script_php = 'if(isset($_POST[\'btn_grabar\'])) {
    $id_hipodromo = $_SESSION[\'id_\'];
    $id_animal = $_POST[\'id_animal\'];
    $nombre = $_POST[\'nombre\'];
}';

En este caso debes acordarte de escapar las comillas sencillas con una contrabarra delante (\ ).
Nowdoc
$script_php = <<<'FINAL'
if(isset($_POST['btn_grabar'])) {
    $id_hipodromo = $_SESSION['id_'];
    $id_animal = $_POST['id_animal'];
    $nombre = $_POST['nombre'];
}
FINAL;

En este caso no debes preocuparte por escapar ningún carácter. Únicamente de no introducir la cadena de final a tu código.
Fíjate que heredoc no es válido porque, al igual que las dobles comillas, también interpreta valores de variables.
Salida al navegador
Si quieres mostrar ese código en el navegador deberás usar la etiqueta HTML
 o  y, además, convertir a entidades los caracteres especiales con htmlspecialchars():

<?= htmlspecialchars($script_php) ?>

O bien:
<?= htmlspecialchars($script_php) ?>

Por cierto, tienes a tu disposición la constante PHP_EOL que representa un final de línea en tu plataforma. Deberías pensar usarla en vez de tu variable $enter.

A: Puedes hacerlo al menos de tres maneras.
Forma 1: Desde código PHP
Escribes todo el fragmento de código en una cadena almacenándolo en una variable. Pero necesitas hacer un cambio en la forma de usar las comillas: al inicio y al final de la cadena debes usar comillas simples ' y en las variables de dentro comillas dobles ", de lo contrario, las variables se interpretarán como tales y no es lo que interesa aquí.
Luego imprimes dicha cadena usando highlight_string. Es una función de PHP que hace lo siguiente según el Manual:

Imprime o devuelve marcas html para una versión con la sintaxis
  remarcada del código de PHP dado usando los colores definidos en el
  remarcador de sintaxis interno de PHP.

De ese modo te mostrará el código identado y (según dice el Manual, con colores, según la configuración de colores de PHP).
Este sería el código:
$strCode='
if(isset($_POST["btn_grabar"]))
    $id_hipodromo = $_SESSION["id_"];
    $id_animal=$_POST["id_animal"];
    $nombre=$_POST["nombre"];';
echo highlight_string($strCode);

Resultado en pantalla:
if(isset($_POST["btn_grabar"]))
    $id_hipodromo = $_SESSION["id_"];
    $id_animal=$_POST["id_animal"];
    $nombre=$_POST["nombre"];

Forma 2: Mezcla de PHP y HTML
Abres un bloque HTML en tu PHP y muestras el código. En este caso, como estás en HTML, puedes dejar lo de las comillas simples como lo tenías originalmente, ya que estás en HTML y las variables no se interpretarán como variables de PHP.
<?php

//Código PHP

?>

if(isset($_POST['btn_grabar']))

    $id_hipodromo = $_SESSION['id_'];

    $id_animal=$_POST['id_animal'];

    $nombre=$_POST['nombre'];

Resultado en pantalla:
if(isset($_POST['btn_grabar']))
$id_hipodromo = $_SESSION['id_'];
$id_animal=$_POST['id_animal'];
$nombre=$_POST['nombre'];

Aquí el problema es que el código no se muestra identado.

Forma 3: con una librería externa
Puedes usar una librería para mostrar código identado y con colores, por ejemplo Google Code Prettify. Esta es la forma que suelen usar los sitios que trabajan mostrando ejemplos de código.
Sólo tendrías que agregar la librería (JS), como cualquier otra:

Y luego abrir una etiqueta así:

Aquí se indica que quiere la sintaxis de PHP mediante lang-php, para el color de código.
Luego escribes dentro el código debidamente identado y al final cierras la etiqueta
.
Veamos una prueba. Aquí estamos en HTML, se puede hacer en PHP, agregando a la cadena lo necesario. Pulsa en Ejecutar, para ver el resultado.

if(isset($_POST['btn_grabar']))
    $id_hipodromo = $_SESSION['id_'];
    $id_animal=$_POST['id_animal'];
    $nombre=$_POST['nombre'];

redpajama_set_name: RedPajamaStackExchange


text:
Etheridge, Cardiff go out in style | Inquirer Sports
sports / Football
Etheridge, Cardiff go out in style
By: Cedelf P. Tupas - Reporter / @cedelfptINQ
Philippine Daily Inquirer / 05:07 AM May 14, 2019
Filipino international Neil Etheridge came up with a performance to remember in Cardiff City's final English Premier League match of the season at historic Old Trafford in Manchester Sunday.
The 29-year-old Etheridge chalked up 10 saves as the Bluebirds pulled off a 2-0 upset over powerhouse Manchester United for his 10th clean sheet of the season, which is seventh-best in the competition.
And while Cardiff is one of the three bottom clubs relegated to the English Championship next season, the Azkals goalkeeper can take pride in the fact that he acquitted himself well in the strongest football league in the world.
His 10 clean sheets and three penalty saves are impressive statistics considering that the Cardiff backline was short of options recently after the season-ending injury to Sol Bamba.
"Still disappointed to be relegated, but the result today showed the team's character against a strong team like Manchester United—a club which has so much history, too," said Etheridge, named Player of the Season by Cardiff last week.
He plans to use the two-month break by visiting the Philippines late this month.
"I've been training and playing nonstop for almost the past two years so it would be nice to get a quick break in the Philippines," said Etheridge, who has 62 appearances for the Philippine national team since 2008.
Key tiff for Kaya against Home United in Singapore
TAGS: Neil Etheridge


text:
Tag: Frank Darabont
REVIEW: Indiana Jones and the Kingdom of the Crystal Skull [2008]
"So much time wasted in human life waiting" I'll tell you, nothing gets one's heart pounding more than a nostalgic theme song score playing during a film. Nothing is more iconic than John Williams' music when it comes to Indiana Jones, unless you count the humor, the adventure, the whip, and the hat. Steven Spielberg even goes out of his way to show the silhouetted professor place said hat upon his head before we even catch a glimpse of the man himself. From the start, Indiana Jones and the Kingdom…
Action/Adventure, Film ReviewsCate Blanchett, David Koepp, Frank Darabont, Harrison Ford, Indiana Jones, John Hurt, John Williams, Karen Allen, Kingdom of the Crystal Skull, Ray Winstone, Sean Connery, Shia LaBeouf, Steven SpielbergLeave a comment
REVIEW: The Mist [2007]
"You're all right Big Bill" I always say to people that Frank Darabont is the only man who can truly make a great Stephen King adaptation. I'm not so sure I have the credentials to state that as fact, but I do anyways. I love The Shawshank Redemption, but never read Rita Hayworth… and I read The Green Mile, but still have yet to watch the film. So, I can't quite compare his work with that of the author, however, that did little to temper my anticipation for his first…
Film Reviews, HorrorAndre Braugher, Frank Darabont, Marcia Gay Harden, Paul Dano, Stephen King, The Green Mile, The Mist, The Shawshank Redemption, There Will Be Blood, Thomas Jane, Toby Jones, William SadlerLeave a comment
(short and sweet and to the point; culled from watching 40 releases. constantly updated as i catch up to those i missed. click poster for review if applicable) #15: Bullets Over Broadway directed by Woody Allen #14: Oleanna directed by David Mamet #13: Reality Bites directed by Ben Stiller #12: Heavenly Creatures directed by Peter Jackson.. #11: Quiz Show directed by Robert Redford.. #10: The AdventuresOf Priscilla,Queen Of The Desert directed by Stephan Elliott #09: Stargate directed by Roland Emmerich. #08: Interview withthe Vampire directed by Neil Jordan #07: The…
UncategorizedAlex Proyas, Ben Stiller, Bullets Over Broadway, Clerks, David Mamet, Frank Darabont, Heavenly Creatures, Interview with the Vampire, Kevin Smith, Léon: The Professional, Natural Born Killers, Neil Jordan, Oleanna, Oliver Stone, Peter Jackson, Pulp Fiction, Quentin Tarantino, Quiz Show, Reality Bites, Rob Minkoff, Robert Redford, Roger Allers, Roland Emmerich, Stargate, Stephan Elliott, The Adventures Of Priscilla Queen Of The Desert, The Crow, The Lion King, The Shawshank Redemption, Woody AllenLeave a comment


text:
Something for the Weekend 12
Our Ancestors' Secret History
I wasn't even going to watch the programme in the first place: The Secret History of Our Streets, it was called. Episode 1 – and the whole series, in fact – was/is about the history of random thoroughfares in outer London. I have virtually no ancestral interest in the social history of the capital … but my fancy new TiVo box recorded the programme by accident, so I thought I'd give it a chance.
The show was great, as it turned out. It concerned the changing face of Deptford High Street – its ups and downs over the years, how it once was, and how it is now. It used maps – most famously Charles Booth's colour-coded Victorian affairs – to illustrate how the area has moved in and out of favour over time with various classes of society. It also contained much in the way of personal accounts and recollections of old-timers who have known the place since the immediate post-war era.
However, the central pillar of the programme was the concept of our streets as communities, and not (as I had anticipated) as structural or architectural entities. It brought the social effects of the 'compulsory purchase orders' and so-called 'slum clearances' of the 1960s sharply into focus. It even produced documentary evidence that these suburban 'improvement schemes' were foisted upon close and helpless communities with little or no justification. Tight-knit and largely happy neighbourhoods of working class people were unthinkingly bulldozed and scattered in the name of high-rise progress.
I've never really lived in such a close and supportive community as that which existed in places like 1960s Deptford. Our family was forced out of just such a neighbourhood in Newcastle's West End and into the more distant suburbs when I was a babe-in-arms (in 1966, before you ask) – at a time when more space and a good deal less intimacy with one's neighbours seemed like a good idea. Deptford's little story was, therefore, something of a revelation to me.
Sure, it was a bit of a hark back to the 'good old, bad old days', but it made me appreciate a mode of existence – a style of living – that had been the accepted norm for many, many centuries. A huge expanse of time when we all relied on each other in a much more immediate way than we do today: extended family, close friends and neighbours all supporting each other – physically, financially and emotionally – on a daily basis. A world that has largely vanished today.
It set me wondering about those aspects of our ancestors' lives which we shall never really know about. We have their names, where they lived, what they did for a living and, of course, the important dates in their lives. But it was the daily interactions with those around them – those who shared their house, their street, their town or suburb – that really made the lives of our forebears what they were. Insights into these vital aspects of former times are so very difficult to come by – indeed most of us will never be lucky enough to catch so much as a glimpse of them. Sadly, recorded history rarely ventures into these important corners of our past.
I'm not sure I have really been able to get over my point. If you can, watch the show to get an idea of just what I'm getting at. It's available in the UK via the BBC iPlayer until 18th July – see here.
Mick Southwick
If you'd like to write a piece for the 'Something for the Weekend' feature, run it past me - I'd really like to hear from you. There is no need to be an expert, a published author, or qualified in any way. You just need to have something interesting to say – or maybe you'd like to promote a product, a research technique or even show off your expertise! And you can even give something a little 'plug' if you wish (a book, or whatever). Get in touch with me at micksouthwick@blueyonder.co.uk . Oh, and it's OK to be controversial!
Maggie 17 June 2012 at 00:11
Yes, I do get your point, and I think it's an important one. And thank you for the reminder to watch this - I'd heard mention of the series, but couldn't remember when it was on or what it was called, but I have family who lived in Deptford, so am very keen to catch this episode while I can.
Friday's Genealogy Selection
A Bit of This & a Bit of That
Archive Move, Welsh Stuff & Libraries
Events, Offers & Newsletters
London, Genetics & Ireland
Saturday Surprise
More FMP News + Other Stuff
Cheap Scottish Wills + Lots More
Opinionated Clergyman
Forthcoming Genealogy Events + Other News
FMP Stuff + Scotland + Ireland + More!
Friday's Genealogical Bits & Pieces
PoW Stuff, New Dorset Records + More
Curious Death / Burial Entries
MyHeritage Landmark + Events
News From Ireland & England, Mainly
More Ancestry Rumours + Other News
FMP, Ancestry & the Irish
Genealogical Oddities
Not Much Happening
Lost Cousins & The Family History Show
The Jubilee Looms...


text:
Q: Alternative to a PostgreSQL cluster restore by promoting the secondary offline replica We have an old PostgreSQL cluster version  10.6 running on REH 7
We use repmgr version 5.0.0
We have one primary replica and a secondary replica  and we use repmgr for managing manula swithcover, promotions, etc.
We do not use repmgr daemon.
The primary uses replication slots for barman and for the secondary replica.
We have to do an update of the database content which will last several hours and we want to be able to restore the database back to the status before the update - in case the update fails.
One option is to restore a backup from barman. This would take a while.
We want to use another approach:

*

*Before starting with the update on the primary, we stop the secondary replica and leave it down until the database content update is completed.

*In case the database content update fails we stop the primary replica

*We promote the secondary replica by running: "repmgr standby promote"
This will allow us to have the new primary replica as the former primary replica was before the database update started.

*Then we delete the former primary and we build the secondary replica with repmgr standby clone

Any issue with this approach  ?
Should I add more steps (like stopping the replication slot before stopping the secondary replica)
Many thanks Mari


text:
package gov.nih.nci.ncicb.cadsr.common.persistence.bc4j;
import oracle.jbo.server.EntityImpl;
import oracle.jbo.server.EntityDefImpl;
import oracle.jbo.server.AttributeDefImpl;
import oracle.jbo.RowIterator;
import oracle.jbo.AttributeList;
import oracle.jbo.server.TransactionEvent;
import oracle.jbo.domain.Number;
import oracle.jbo.domain.Date;
import oracle.jbo.domain.BlobDomain;
import oracle.jbo.Key;
//  ---------------------------------------------------------------
//  ---    File generated by Oracle Business Components for Java.
//  ---------------------------------------------------------------

public class ReferenceBlobsImpl extends EntityImpl  {
  public static final int RDIDSEQ = 0;
  public static final int NAME = 1;
  public static final int MIMETYPE = 2;
  public static final int DOCSIZE = 3;
  public static final int DADCHARSET = 4;
  public static final int LASTUPDATED = 5;
  public static final int CONTENTTYPE = 6;
  public static final int BLOBCONTENT = 7;
  public static final int CREATEDBY = 8;
  public static final int DATECREATED = 9;
  public static final int MODIFIEDBY = 10;
  public static final int DATEMODIFIED = 11;
  public static final int REFERENCEDOCUMENTS = 12;

  private static EntityDefImpl mDefinitionObject;

  /**
   *
   * This is the default constructor (do not remove)
   */
  public ReferenceBlobsImpl() {
  }

  /**
   *
   *  Retrieves the definition object for this instance class.
   */
  public static synchronized EntityDefImpl getDefinitionObject()
  {
    if (mDefinitionObject == null)
    {
      mDefinitionObject = (EntityDefImpl)EntityDefImpl.findDefObject("gov.nih.nci.ncicb.cadsr.common.persistence.bc4j.ReferenceBlobs");
    }
    return mDefinitionObject;
  }

  /**
   *
   * Add attribute defaulting logic in this method.
   */
  protected void create(AttributeList attributeList) {
    super.create(attributeList);
  }

  /**
   *
   * Add entity remove logic in this method.
   */
  public void remove() {
    super.remove();
  }

  /**
   *
   * Add Entity validation code in this method.
   */
  protected void validateEntity() {
    super.validateEntity();
  }

  /**
   *
   * Add locking logic here.
   */
  public void lock() {
    super.lock();
  }

  /**
   *
   * Custom DML update/insert/delete logic here.
   */
  protected void doDML(int operation, TransactionEvent e) {
    super.doDML(operation, e);
  }

  /**
   *
   * Gets the attribute value for RdIdseq, using the alias name RdIdseq
   */
  public String getRdIdseq() {
    return (String)getAttributeInternal(RDIDSEQ);
  }

  /**
   *
   * Sets value as the attribute value for RdIdseq
   */
  public void setRdIdseq(String value) {
    setAttributeInternal(RDIDSEQ, value);
  }

  /**
   *
   * Gets the attribute value for Name, using the alias name Name
   */
  public String getName() {
    return (String)getAttributeInternal(NAME);
  }

  /**
   *
   * Sets value as the attribute value for Name
   */
  public void setName(String value) {
    setAttributeInternal(NAME, value);
  }

  /**
   *
   * Gets the attribute value for MimeType, using the alias name MimeType
   */
  public String getMimeType() {
    return (String)getAttributeInternal(MIMETYPE);
  }

  /**
   *
   * Sets value as the attribute value for MimeType
   */
  public void setMimeType(String value) {
    setAttributeInternal(MIMETYPE, value);
  }

  /**
   *
   * Gets the attribute value for DocSize, using the alias name DocSize
   */
  public Number getDocSize() {
    return (Number)getAttributeInternal(DOCSIZE);
  }

  /**
   *
   * Sets value as the attribute value for DocSize
   */
  public void setDocSize(Number value) {
    setAttributeInternal(DOCSIZE, value);
  }

  /**
   *
   * Gets the attribute value for DadCharset, using the alias name DadCharset
   */
  public String getDadCharset() {
    return (String)getAttributeInternal(DADCHARSET);
  }

  /**
   *
   * Sets value as the attribute value for DadCharset
   */
  public void setDadCharset(String value) {
    setAttributeInternal(DADCHARSET, value);
  }

  /**
   *
   * Gets the attribute value for LastUpdated, using the alias name LastUpdated
   */
  public Date getLastUpdated() {
    return (Date)getAttributeInternal(LASTUPDATED);
  }

  /**
   *
   * Sets value as the attribute value for LastUpdated
   */
  public void setLastUpdated(Date value) {
    setAttributeInternal(LASTUPDATED, value);
  }

  /**
   *
   * Gets the attribute value for ContentType, using the alias name ContentType
   */
  public String getContentType() {
    return (String)getAttributeInternal(CONTENTTYPE);
  }

  /**
   *
   * Sets value as the attribute value for ContentType
   */
  public void setContentType(String value) {
    setAttributeInternal(CONTENTTYPE, value);
  }

  /**
   *
   * Gets the attribute value for BlobContent, using the alias name BlobContent
   */
  public BlobDomain getBlobContent() {
    return (BlobDomain)getAttributeInternal(BLOBCONTENT);
  }

  /**
   *
   * Sets value as the attribute value for BlobContent
   */
  public void setBlobContent(BlobDomain value) {
    setAttributeInternal(BLOBCONTENT, value);
  }

  /**
   *
   * Gets the attribute value for CreatedBy, using the alias name CreatedBy
   */
  public String getCreatedBy() {
    return (String)getAttributeInternal(CREATEDBY);
  }

  /**
   *
   * Sets value as the attribute value for CreatedBy
   */
  public void setCreatedBy(String value) {
    setAttributeInternal(CREATEDBY, value);
  }

  /**
   *
   * Gets the attribute value for DateCreated, using the alias name DateCreated
   */
  public Date getDateCreated() {
    return (Date)getAttributeInternal(DATECREATED);
  }

  /**
   *
   * Sets value as the attribute value for DateCreated
   */
  public void setDateCreated(Date value) {
    setAttributeInternal(DATECREATED, value);
  }

  /**
   *
   * Gets the attribute value for ModifiedBy, using the alias name ModifiedBy
   */
  public String getModifiedBy() {
    return (String)getAttributeInternal(MODIFIEDBY);
  }

  /**
   *
   * Sets value as the attribute value for ModifiedBy
   */
  public void setModifiedBy(String value) {
    setAttributeInternal(MODIFIEDBY, value);
  }

  /**
   *
   * Gets the attribute value for DateModified, using the alias name DateModified
   */
  public Date getDateModified() {
    return (Date)getAttributeInternal(DATEMODIFIED);
  }

  /**
   *
   * Sets value as the attribute value for DateModified
   */
  public void setDateModified(Date value) {
    setAttributeInternal(DATEMODIFIED, value);
  }
  //  Generated method. Do not modify.

  protected Object getAttrInvokeAccessor(int index, AttributeDefImpl attrDef) throws Exception {
    switch (index)
      {
      case RDIDSEQ:
        return getRdIdseq();
      case NAME:
        return getName();
      case MIMETYPE:
        return getMimeType();
      case DOCSIZE:
        return getDocSize();
      case DADCHARSET:
        return getDadCharset();
      case LASTUPDATED:
        return getLastUpdated();
      case CONTENTTYPE:
        return getContentType();
      case BLOBCONTENT:
        return getBlobContent();
      case CREATEDBY:
        return getCreatedBy();
      case DATECREATED:
        return getDateCreated();
      case MODIFIEDBY:
        return getModifiedBy();
      case DATEMODIFIED:
        return getDateModified();
      case REFERENCEDOCUMENTS:
        return getReferenceDocuments();
      default:
        return super.getAttrInvokeAccessor(index, attrDef);
      }
  }
  //  Generated method. Do not modify.

  protected void setAttrInvokeAccessor(int index, Object value, AttributeDefImpl attrDef) throws Exception {
    switch (index)
      {
      case RDIDSEQ:
        setRdIdseq((String)value);
        return;
      case NAME:
        setName((String)value);
        return;
      case MIMETYPE:
        setMimeType((String)value);
        return;
      case DOCSIZE:
        setDocSize((Number)value);
        return;
      case DADCHARSET:
        setDadCharset((String)value);
        return;
      case LASTUPDATED:
        setLastUpdated((Date)value);
        return;
      case CONTENTTYPE:
        setContentType((String)value);
        return;
      case BLOBCONTENT:
        setBlobContent((BlobDomain)value);
        return;
      case CREATEDBY:
        setCreatedBy((String)value);
        return;
      case DATECREATED:
        setDateCreated((Date)value);
        return;
      case MODIFIEDBY:
        setModifiedBy((String)value);
        return;
      case DATEMODIFIED:
        setDateModified((Date)value);
        return;
      default:
        super.setAttrInvokeAccessor(index, value, attrDef);
        return;
      }
  }

  /**
   *
   * Gets the associated entity ReferenceDocumentsImpl
   */
  public ReferenceDocumentsImpl getReferenceDocuments() {
    return (ReferenceDocumentsImpl)getAttributeInternal(REFERENCEDOCUMENTS);
  }

  /**
   *
   * Sets value as the associated entity ReferenceDocumentsImpl
   */
  public void setReferenceDocuments(ReferenceDocumentsImpl value) {
    setAttributeInternal(REFERENCEDOCUMENTS, value);
  }

  /**
   *
   *  Creates a Key object based on given key constituents
   */
  public static Key createPrimaryKey(String name)
  {
    return new Key(new Object[] {name});
  }

}


For Mains: Significance and the need for legislation on this.
Context: The Ministry of Health and Family Welfare has issued a notification for bringing the Human Immunodeficiency Virus and Acquired Immune Deficiency Syndrome (Prevention and Control) Act, 2017 in force from 10th September, 2018.
Provisions related to the role of governments: As per the Act, central and state governments are obliged to provide for anti-retroviral therapy (ART) and management of opportunistic infections (infections that take advantage of weakness in the immune system and occur frequently). It also prohibits specific acts of discrimination by the state, or any other person, against HIV-positive people, or those living with such people.
Provisions related to discrimination: It lays down penal provisions for any discrimination practised against a person with HIV/AIDS and breach of confidentiality. The protection mandated extends to the fields of employment, healthcare services, educational services, public facilities, property rights, holding public office, and insurance. It also provides for confidentiality of HIV-related information and makes it necessary to get informed consent for undertaking HIV tests, medical treatment and research.
Provisions related to guardianship: Provisions related to guardianship are also specified. A person between the age of 12 to 18 years who has sufficient maturity in understanding and managing the affairs of his HIV or AIDS affected family shall be competent to act as a guardian of another sibling below 18 years of age. The guardianship will apply in matters relating to admission to educational establishments, operating bank accounts, managing property, care and treatment, amongst others.
Role of courts: Cases relating to HIV positive persons shall be disposed off by the court on a priority basis. In any legal proceeding, if an HIV infected or affected person is a party, the court may pass orders that the proceedings be conducted (a) by suppressing the identity of the person, (b) in camera, and (c) to restrain any person from publishing information that discloses the identity of the applicant. When passing any order with regard to a maintenance application filed by an HIV infected or affected person, the court shall take into account the medical expenses incurred by the applicant.
There are approximately 21 lakh persons estimated to be living with HIV in India and the percentage of patients receiving anti-retroviral therapy (ART) treatment currently stands at a mere 25.82% as against the global percentage of 41%, according to the 2015 Global Burden of Diseases (GBD).
Context: Ministry of External Affairs (MEA) and the Telecommunications Consultants India Ltd (TCIL) have signed an Agreement for the implementation of e-VidyaBharati and e-AarogyaBharati (e-VBAB) Network Project. The project is hailed as a digital bridge of knowledge and health between India and Africa.
For Prelims: PMMY- key features.
For Mains: Significance of the scheme and concerns raised over loans disbursed under the scheme, how can these loans be prevented from turning into NPAs.
Context: Former RBI Governor Raghuram Rajan has cautioned that the next crisis in India's banking sector could come from loans given to the unorganised micro and small businesses, called MUDRA loans, and credit extended through the Kisan credit card.
He has also cautioned the government to refrain from setting ambitious credit targets or waiving loans. He also flagged the Credit Guarantee Scheme for MSMEs, run by the Small Industries Development Bank of India, calling it "a growing contingent liability" that needs to be examined with urgency.
For Prelims and Mains: Apsara and Apsara- U- Key features and significance of these reactors.
Context: THE BHABHA Atomic Research Centre has recommissioned an upgraded version of 'Apsara', the country's oldest research reactor that was decommissioned almost a decade ago. Apsara is now operational as 'Apsara-U' on Trombay campus of Maharashtra.
For Prelims: Objectives and features of ICTAI.
For Mains: AI- need, concerns, potential and need for legislation.
Context: NITI Aayog, Intel, and Tata Institute of Fundamental Research (TIFR) are collaborating to set up a Model International Center for Transformative Artificial Intelligence (ICTAI) towards developing and deploying AI-led application-based research projects.
Through this collaborative effort, the model ICTAI is chartered to develop AI foundational frameworks, tools and assets, including curated datasets and unique AI algorithms.
Another key area of its focus will be collaboration with industry leaders, startups, and AI services and product companies to productize technologies and IP that are developed at the model ICTAI. And finally, the goal is to support skilling and talent development for world-class AI talent.
Artificial Intelligence comes from computer systems that have been programmed to — or have learnt to — do tasks that would otherwise require human intelligence. Many apps and software are already making mundane work easier by doing a certain part of it for us, based on acquired intelligence.
Automation threatens 69% of the jobs in India, while it's 77% in China, according to a World Bank research. The transition is expected to happen in a decade, according to experts. Therefore, if automation is not planned well and addressed holistically, it is a disaster in the making.
While there is a risk to jobs due to these trends, the good news is that a huge number of new jobs are getting created as well in areas like cybersecurity, cloud, big data, machine learning and AI. The new job roles that will dominate the IT workforce are within digital domains such as big data, artificial intelligence, Internet of Things (IoT), cloud computing and cybersecurity. It is clearly a time of career pivot for IT professionals to make sure they are where the growth is.
The Union ministry of electronics and information technology, in October 2017, set up an internal committee to advise the government on a policy on artificial intelligence (AI). The expert committee will advise the IT ministry on the most apt technologies for India. The government's main focus is to reduce cyber attacks with AI.
The artificial intelligence market is estimated to touch $153 billion in 2020 and expected to grow at a compounded annual growth rate of 45.4% from 2016 to 2022. However, AI is widely seen as a major challenge in generation of employment as many companies are likely to depend more on it to cut down on human resources.
The strategy includes developing methods for human machine interactions; ensuring safety and security of AI systems; creating a competent workforce in line with AI and R&D needs, understanding and addressing the ethical, legal and societal implications of AI, measuring and evaluating AI technologies through standards and benchmarks, among others.
For Prelims and Mains: Features and significance of the ship.
Context: Hindustan Shipyard Limited (HSL) is gearing up to undertake sea trials of India's first missile tracking ship by the first week of October.
This will be the first of its kind ocean surveillance ship being built as part of the efforts to strengthen the country's strategic weapons programme.
Its induction will put India in the elite of club of a few countries that have such a sophisticated ocean surveillance ship.
It has the capacity to carry 300-strong crew with hi-tech gadgets and communication equipment, powered by two diesel engines, and a large deck capable of helicopter landing.
As part of the ongoing Indo-US defence cooperation, a joint military training Exercise Yudh Abhyas 2018 will be held at Chaubattia in Uttarakhand. This will be the 14th edition of the joint military exercise hosted alternately by both countries.
Union Ministry of Railways has launched Rail Sahyog web portal (www.railsahyog.in).
It will provide platform for Corporates and PSUs to fund creation of amenities at railway stations through Corporate Social Responsibility (CSR) funds.
This portal will allow companies to register their requests for contributing to create amenities at railway stations through their CSR funds. These requests will be processed by Railway officials and based on tprinciple of first come first serve, requests will be shortlisted.
Selected applicants will be intimated to deposit the funds with Railways or its nominated agencies like RITES or RAILTEL etc. The nominated agency will get the work executed thereafter.
It will provide opportunity for industry, companies, associations to collaborate with Indian Railways. Fund utilized for creation of amenities will be beneficial for passengers and for neighbourhood of railway vicinity.