text:
#include <linux/firmware.h>

#include "decl.h"
#include "ioctl.h"
#include "util.h"
#include "fw.h"
#include "main.h"
#include "wmm.h"
#include "11n.h"
#include "pcie.h"

#define PCIE_VERSION	"1.0"
#define DRV_NAME        "Marvell mwifiex PCIe"

static u8 user_rmmod;

static struct mwifiex_if_ops pcie_ops;

static struct semaphore add_remove_card_sem;
static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter);
static int mwifiex_pcie_resume(struct pci_dev *pdev);

/*
 * This function is called after skb allocation to update
 * "skb->cb" with physical address of data pointer.
 */
static phys_addr_t *mwifiex_update_sk_buff_pa(struct sk_buff *skb)
{
	phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb);

	*buf_pa = (phys_addr_t)virt_to_phys(skb->data);

	return buf_pa;
}

/*
 * This function reads sleep cookie and checks if FW is ready
 */
static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
{
	u32 *cookie_addr;
	struct pcie_service_card *card = adapter->card;

	if (card->sleep_cookie) {
		cookie_addr = (u32 *)card->sleep_cookie->data;
		dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n",
			*cookie_addr);
		if (*cookie_addr == FW_AWAKE_COOKIE)
			return true;
	}

	return false;
}

/*
 * This function probes an mwifiex device and registers it. It allocates
 * the card structure, enables PCIE function number and initiates the
 * device registration and initialization procedure by adding a logical
 * interface.
 */
static int mwifiex_pcie_probe(struct pci_dev *pdev,
					const struct pci_device_id *ent)
{
	struct pcie_service_card *card;

	pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
		 pdev->vendor, pdev->device, pdev->revision);

	card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
	if (!card)
		return -ENOMEM;

	card->dev = pdev;

	if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
			     MWIFIEX_PCIE)) {
		pr_err("%s failed\n", __func__);
		kfree(card);
		return -1;
	}

	return 0;
}

/*
 * This function removes the interface and frees up the card structure.
 */
static void mwifiex_pcie_remove(struct pci_dev *pdev)
{
	struct pcie_service_card *card;
	struct mwifiex_adapter *adapter;
	struct mwifiex_private *priv;
	int i;

	card = pci_get_drvdata(pdev);
	if (!card)
		return;

	adapter = card->adapter;
	if (!adapter || !adapter->priv_num)
		return;

	if (user_rmmod) {
#ifdef CONFIG_PM
		if (adapter->is_suspended)
			mwifiex_pcie_resume(pdev);
#endif

		for (i = 0; i < adapter->priv_num; i++)
			if ((GET_BSS_ROLE(adapter->priv[i]) ==
			     MWIFIEX_BSS_ROLE_STA) &&
			    adapter->priv[i]->media_connected)
				mwifiex_deauthenticate(adapter->priv[i], NULL);

		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);

		mwifiex_disable_auto_ds(priv);

		mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
	}

	mwifiex_remove_card(card->adapter, &add_remove_card_sem);
	kfree(card);
}

/*
 * Kernel needs to suspend all functions separately. Therefore all
 * registered functions must have drivers with suspend and resume
 * methods. Failing that the kernel simply removes the whole card.
 *
 * If already not suspended, this function allocates and sends a host
 * sleep activate request to the firmware and turns off the traffic.
 */
static int mwifiex_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct mwifiex_adapter *adapter;
	struct pcie_service_card *card;
	int hs_actived, i;

	if (pdev) {
		card = (struct pcie_service_card *) pci_get_drvdata(pdev);
		if (!card || !card->adapter) {
			pr_err("Card or adapter structure is not valid\n");
			return 0;
		}
	} else {
		pr_err("PCIE device is not specified\n");
		return 0;
	}

	adapter = card->adapter;

	hs_actived = mwifiex_enable_hs(adapter);

	/* Indicate device suspended */
	adapter->is_suspended = true;

	for (i = 0; i < adapter->priv_num; i++)
		netif_carrier_off(adapter->priv[i]->netdev);

	return 0;
}

/*
 * Kernel needs to suspend all functions separately. Therefore all
 * registered functions must have drivers with suspend and resume
 * methods. Failing that the kernel simply removes the whole card.
 *
 * If already not resumed, this function turns on the traffic and
 * sends a host sleep cancel request to the firmware.
 */
static int mwifiex_pcie_resume(struct pci_dev *pdev)
{
	struct mwifiex_adapter *adapter;
	struct pcie_service_card *card;
	int i;

	if (pdev) {
		card = (struct pcie_service_card *) pci_get_drvdata(pdev);
		if (!card || !card->adapter) {
			pr_err("Card or adapter structure is not valid\n");
			return 0;
		}
	} else {
		pr_err("PCIE device is not specified\n");
		return 0;
	}

	adapter = card->adapter;

	if (!adapter->is_suspended) {
		dev_warn(adapter->dev, "Device already resumed\n");
		return 0;
	}

	adapter->is_suspended = false;

	for (i = 0; i < adapter->priv_num; i++)
		if (adapter->priv[i]->media_connected)
			netif_carrier_on(adapter->priv[i]->netdev);

	mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
			  MWIFIEX_ASYNC_CMD);

	return 0;
}

#define PCIE_VENDOR_ID_MARVELL              (0x11ab)
#define PCIE_DEVICE_ID_MARVELL_88W8766P		(0x2b30)

static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = {
	{
		PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P,
		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
	},
	{},
};

MODULE_DEVICE_TABLE(pci, mwifiex_ids);

/* PCI Device Driver */
static struct pci_driver __refdata mwifiex_pcie = {
	.name     = "mwifiex_pcie",
	.id_table = mwifiex_ids,
	.probe    = mwifiex_pcie_probe,
	.remove   = mwifiex_pcie_remove,
#ifdef CONFIG_PM
	/* Power Management Hooks */
	.suspend  = mwifiex_pcie_suspend,
	.resume   = mwifiex_pcie_resume,
#endif
};

/*
 * This function writes data into PCIE card register.
 */
static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
{
	struct pcie_service_card *card = adapter->card;

	iowrite32(data, card->pci_mmap1 + reg);

	return 0;
}

/*
 * This function reads data from PCIE card register.
 */
static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
{
	struct pcie_service_card *card = adapter->card;

	*data = ioread32(card->pci_mmap1 + reg);

	return 0;
}

/*
 * This function wakes up the card.
 *
 * A host power up command is written to the card configuration
 * register to wake up the card.
 */
static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
{
	int i = 0;

	while (mwifiex_pcie_ok_to_access_hw(adapter)) {
		i++;
		usleep_range(10, 20);
		/* 50ms max wait */
		if (i == 5000)
			break;
	}

	dev_dbg(adapter->dev, "event: Wakeup device...\n");

	/* Enable interrupts or any chip access will wakeup device */
	if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK, HOST_INTR_MASK)) {
		dev_warn(adapter->dev, "Enable host interrupt failed\n");
		return -1;
	}

	dev_dbg(adapter->dev, "PCIE wakeup: Setting PS_STATE_AWAKE\n");
	adapter->ps_state = PS_STATE_AWAKE;

	return 0;
}

/*
 * This function is called after the card has woken up.
 *
 * The card configuration register is reset.
 */
static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
{
	dev_dbg(adapter->dev, "cmd: Wakeup device completed\n");

	return 0;
}

/*
 * This function disables the host interrupt.
 *
 * The host interrupt mask is read, the disable bit is reset and
 * written back to the card host interrupt mask register.
 */
static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter)
{
	if (mwifiex_pcie_ok_to_access_hw(adapter)) {
		if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
				      0x00000000)) {
			dev_warn(adapter->dev, "Disable host interrupt failed\n");
			return -1;
		}
	}

	return 0;
}

/*
 * This function enables the host interrupt.
 *
 * The host interrupt enable mask is written to the card
 * host interrupt mask register.
 */
static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter)
{
	if (mwifiex_pcie_ok_to_access_hw(adapter)) {
		/* Simply write the mask to the register */
		if (mwifiex_write_reg(adapter, PCIE_HOST_INT_MASK,
				      HOST_INTR_MASK)) {
			dev_warn(adapter->dev, "Enable host interrupt failed\n");
			return -1;
		}
	}

	return 0;
}

/*
 * This function creates buffer descriptor ring for TX
 */
static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct sk_buff *skb;
	int i;
	phys_addr_t *buf_pa;

	/*
	 * driver maintaines the write pointer and firmware maintaines the read
	 * pointer. The write pointer starts at 0 (zero) while the read pointer
	 * starts at zero with rollover bit set
	 */
	card->txbd_wrptr = 0;
	card->txbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;

	/* allocate shared memory for the BD ring and divide the same in to
	   several descriptors */
	card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
							MWIFIEX_MAX_TXRX_BD;
	dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
		card->txbd_ring_size);
	card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL);
	if (!card->txbd_ring_vbase) {
		dev_err(adapter->dev, "Unable to alloc buffer for txbd ring\n");
		return -ENOMEM;
	}
	card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase);

	dev_dbg(adapter->dev,
		"info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
		card->txbd_ring_vbase, (u32)card->txbd_ring_pbase,
		(u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
		card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
				     (card->txbd_ring_vbase +
				      (sizeof(struct mwifiex_pcie_buf_desc)
				       * i));

		/* Allocate buffer here so that firmware can DMA data from it */
		skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
		if (!skb) {
			dev_err(adapter->dev, "Unable to allocate skb for TX ring.\n");
			kfree(card->txbd_ring_vbase);
			return -ENOMEM;
		}
		buf_pa = mwifiex_update_sk_buff_pa(skb);

		skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE);
		dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, "
			"buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
			skb, skb->data, (u32)*buf_pa,
			(u32)(((u64)*buf_pa >> 32)), skb->len);

		card->tx_buf_list[i] = skb;
		card->txbd_ring[i]->paddr = *buf_pa;
		card->txbd_ring[i]->len = (u16)skb->len;
		card->txbd_ring[i]->flags = 0;
	}

	return 0;
}

static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	int i;

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
		if (card->tx_buf_list[i])
			dev_kfree_skb_any(card->tx_buf_list[i]);
		card->tx_buf_list[i] = NULL;
		card->txbd_ring[i]->paddr = 0;
		card->txbd_ring[i]->len = 0;
		card->txbd_ring[i]->flags = 0;
		card->txbd_ring[i] = NULL;
	}

	kfree(card->txbd_ring_vbase);
	card->txbd_ring_size = 0;
	card->txbd_wrptr = 0;
	card->txbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
	card->txbd_ring_vbase = NULL;

	return 0;
}

/*
 * This function creates buffer descriptor ring for RX
 */
static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct sk_buff *skb;
	int i;
	phys_addr_t *buf_pa;

	/*
	 * driver maintaines the read pointer and firmware maintaines the write
	 * pointer. The write pointer starts at 0 (zero) while the read pointer
	 * starts at zero with rollover bit set
	 */
	card->rxbd_wrptr = 0;
	card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;

	card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
							MWIFIEX_MAX_TXRX_BD;
	dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
		card->rxbd_ring_size);
	card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL);
	if (!card->rxbd_ring_vbase) {
		dev_err(adapter->dev, "Unable to allocate buffer for "
				"rxbd_ring.\n");
		return -ENOMEM;
	}
	card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase);

	dev_dbg(adapter->dev,
		"info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
		card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
		(u32)((u64)card->rxbd_ring_pbase >> 32),
		card->rxbd_ring_size);

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
		card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
				     (card->rxbd_ring_vbase +
				      (sizeof(struct mwifiex_pcie_buf_desc)
				       * i));

		/* Allocate skb here so that firmware can DMA data from it */
		skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
		if (!skb) {
			dev_err(adapter->dev,
				"Unable to allocate skb for RX ring.\n");
			kfree(card->rxbd_ring_vbase);
			return -ENOMEM;
		}
		buf_pa = mwifiex_update_sk_buff_pa(skb);
		skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE);

		dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, "
			"buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
			skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
			skb->len);

		card->rx_buf_list[i] = skb;
		card->rxbd_ring[i]->paddr = *buf_pa;
		card->rxbd_ring[i]->len = (u16)skb->len;
		card->rxbd_ring[i]->flags = 0;
	}

	return 0;
}

/*
 * This function deletes Buffer descriptor ring for RX
 */
static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	int i;

	for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
		if (card->rx_buf_list[i])
			dev_kfree_skb_any(card->rx_buf_list[i]);
		card->rx_buf_list[i] = NULL;
		card->rxbd_ring[i]->paddr = 0;
		card->rxbd_ring[i]->len = 0;
		card->rxbd_ring[i]->flags = 0;
		card->rxbd_ring[i] = NULL;
	}

	kfree(card->rxbd_ring_vbase);
	card->rxbd_ring_size = 0;
	card->rxbd_wrptr = 0;
	card->rxbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
	card->rxbd_ring_vbase = NULL;

	return 0;
}

/*
 * This function creates buffer descriptor ring for Events
 */
static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct sk_buff *skb;
	int i;
	phys_addr_t *buf_pa;

	/*
	 * driver maintaines the read pointer and firmware maintaines the write
	 * pointer. The write pointer starts at 0 (zero) while the read pointer
	 * starts at zero with rollover bit set
	 */
	card->evtbd_wrptr = 0;
	card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;

	card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
							MWIFIEX_MAX_EVT_BD;
	dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
		card->evtbd_ring_size);
	card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL);
	if (!card->evtbd_ring_vbase) {
		dev_err(adapter->dev,
			"Unable to allocate buffer. Terminating download\n");
		return -ENOMEM;
	}
	card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase);

	dev_dbg(adapter->dev,
		"info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
		card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
		(u32)((u64)card->evtbd_ring_pbase >> 32),
		card->evtbd_ring_size);

	for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
		card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
				      (card->evtbd_ring_vbase +
				       (sizeof(struct mwifiex_pcie_buf_desc)
					* i));

		/* Allocate skb here so that firmware can DMA data from it */
		skb = dev_alloc_skb(MAX_EVENT_SIZE);
		if (!skb) {
			dev_err(adapter->dev,
				"Unable to allocate skb for EVENT buf.\n");
			kfree(card->evtbd_ring_vbase);
			return -ENOMEM;
		}
		buf_pa = mwifiex_update_sk_buff_pa(skb);
		skb_put(skb, MAX_EVENT_SIZE);

		dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, "
			"buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
			skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
			skb->len);

		card->evt_buf_list[i] = skb;
		card->evtbd_ring[i]->paddr = *buf_pa;
		card->evtbd_ring[i]->len = (u16)skb->len;
		card->evtbd_ring[i]->flags = 0;
	}

	return 0;
}

/*
 * This function deletes Buffer descriptor ring for Events
 */
static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	int i;

	for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
		if (card->evt_buf_list[i])
			dev_kfree_skb_any(card->evt_buf_list[i]);
		card->evt_buf_list[i] = NULL;
		card->evtbd_ring[i]->paddr = 0;
		card->evtbd_ring[i]->len = 0;
		card->evtbd_ring[i]->flags = 0;
		card->evtbd_ring[i] = NULL;
	}

	kfree(card->evtbd_ring_vbase);
	card->evtbd_wrptr = 0;
	card->evtbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND;
	card->evtbd_ring_size = 0;
	card->evtbd_ring_vbase = NULL;

	return 0;
}

/*
 * This function allocates a buffer for CMDRSP
 */
static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct sk_buff *skb;

	/* Allocate memory for receiving command response data */
	skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
	if (!skb) {
		dev_err(adapter->dev,
			"Unable to allocate skb for command response data.\n");
		return -ENOMEM;
	}
	mwifiex_update_sk_buff_pa(skb);
	skb_put(skb, MWIFIEX_UPLD_SIZE);
	card->cmdrsp_buf = skb;

	skb = NULL;
	/* Allocate memory for sending command to firmware */
	skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER);
	if (!skb) {
		dev_err(adapter->dev,
			"Unable to allocate skb for command data.\n");
		return -ENOMEM;
	}
	mwifiex_update_sk_buff_pa(skb);
	skb_put(skb, MWIFIEX_SIZE_OF_CMD_BUFFER);
	card->cmd_buf = skb;

	return 0;
}

/*
 * This function deletes a buffer for CMDRSP
 */
static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card;

	if (!adapter)
		return 0;

	card = adapter->card;

	if (card && card->cmdrsp_buf)
		dev_kfree_skb_any(card->cmdrsp_buf);

	if (card && card->cmd_buf)
		dev_kfree_skb_any(card->cmd_buf);

	return 0;
}

/*
 * This function allocates a buffer for sleep cookie
 */
static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
{
	struct sk_buff *skb;
	struct pcie_service_card *card = adapter->card;

	/* Allocate memory for sleep cookie */
	skb = dev_alloc_skb(sizeof(u32));
	if (!skb) {
		dev_err(adapter->dev,
			"Unable to allocate skb for sleep cookie!\n");
		return -ENOMEM;
	}
	mwifiex_update_sk_buff_pa(skb);
	skb_put(skb, sizeof(u32));

	/* Init val of Sleep Cookie */
	*(u32 *)skb->data = FW_AWAKE_COOKIE;

	dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
		*((u32 *)skb->data));

	/* Save the sleep cookie */
	card->sleep_cookie = skb;

	return 0;
}

/*
 * This function deletes buffer for sleep cookie
 */
static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card;

	if (!adapter)
		return 0;

	card = adapter->card;

	if (card && card->sleep_cookie) {
		dev_kfree_skb_any(card->sleep_cookie);
		card->sleep_cookie = NULL;
	}

	return 0;
}

/*
 * This function sends data buffer to device
 */
static int
mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb)
{
	struct pcie_service_card *card = adapter->card;
	u32 wrindx, rdptr;
	phys_addr_t *buf_pa;
	__le16 *tmp;

	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		mwifiex_pm_wakeup_card(adapter);

	/* Read the TX ring read pointer set by firmware */
	if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) {
		dev_err(adapter->dev,
			"SEND DATA: failed to read REG_TXBD_RDPTR\n");
		return -1;
	}

	wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK;

	dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr,
		card->txbd_wrptr);
	if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) !=
			(rdptr & MWIFIEX_TXBD_MASK)) ||
	    ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
			(rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
		struct sk_buff *skb_data;
		u8 *payload;

		adapter->data_sent = true;
		skb_data = card->tx_buf_list[wrindx];
		memcpy(skb_data->data, skb->data, skb->len);
		payload = skb_data->data;
		tmp = (__le16 *)&payload[0];
		*tmp = cpu_to_le16((u16)skb->len);
		tmp = (__le16 *)&payload[2];
		*tmp = cpu_to_le16(MWIFIEX_TYPE_DATA);
		skb_put(skb_data, MWIFIEX_RX_DATA_BUF_SIZE - skb_data->len);
		skb_trim(skb_data, skb->len);
		buf_pa = MWIFIEX_SKB_PACB(skb_data);
		card->txbd_ring[wrindx]->paddr = *buf_pa;
		card->txbd_ring[wrindx]->len = (u16)skb_data->len;
		card->txbd_ring[wrindx]->flags = MWIFIEX_BD_FLAG_FIRST_DESC |
						MWIFIEX_BD_FLAG_LAST_DESC;

		if ((++card->txbd_wrptr & MWIFIEX_TXBD_MASK) ==
							MWIFIEX_MAX_TXRX_BD)
			card->txbd_wrptr = ((card->txbd_wrptr &
						MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
						MWIFIEX_BD_FLAG_ROLLOVER_IND);

		/* Write the TX ring write pointer in to REG_TXBD_WRPTR */
		if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR,
				      card->txbd_wrptr)) {
			dev_err(adapter->dev,
				"SEND DATA: failed to write REG_TXBD_WRPTR\n");
			return 0;
		}

		/* Send the TX ready interrupt */
		if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
				      CPU_INTR_DNLD_RDY)) {
			dev_err(adapter->dev,
				"SEND DATA: failed to assert door-bell intr\n");
			return -1;
		}
		dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
			"%#x> and sent packet to firmware successfully\n",
			rdptr, card->txbd_wrptr);
	} else {
		dev_dbg(adapter->dev,
			"info: TX Ring full, can't send packets to fw\n");
		adapter->data_sent = true;
		/* Send the TX ready interrupt */
		if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
				      CPU_INTR_DNLD_RDY))
			dev_err(adapter->dev,
				"SEND DATA: failed to assert door-bell intr\n");
		return -EBUSY;
	}

	return 0;
}

/*
 * This function handles received buffer ring and
 * dispatches packets to upper
 */
static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	u32 wrptr, rd_index;
	int ret = 0;
	struct sk_buff *skb_tmp = NULL;

	/* Read the RX ring Write pointer set by firmware */
	if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
		dev_err(adapter->dev,
			"RECV DATA: failed to read REG_TXBD_RDPTR\n");
		ret = -1;
		goto done;
	}

	while (((wrptr & MWIFIEX_RXBD_MASK) !=
		(card->rxbd_rdptr & MWIFIEX_RXBD_MASK)) ||
	       ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) ==
		(card->rxbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
		struct sk_buff *skb_data;
		u16 rx_len;

		rd_index = card->rxbd_rdptr & MWIFIEX_RXBD_MASK;
		skb_data = card->rx_buf_list[rd_index];

		/* Get data length from interface header -
		   first byte is len, second byte is type */
		rx_len = *((u16 *)skb_data->data);
		dev_dbg(adapter->dev,
			"info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
			card->rxbd_rdptr, wrptr, rx_len);
		skb_tmp = dev_alloc_skb(rx_len);
		if (!skb_tmp) {
			dev_dbg(adapter->dev,
				"info: Failed to alloc skb for RX\n");
			ret = -EBUSY;
			goto done;
		}

		skb_put(skb_tmp, rx_len);

		memcpy(skb_tmp->data, skb_data->data + INTF_HEADER_LEN, rx_len);
		if ((++card->rxbd_rdptr & MWIFIEX_RXBD_MASK) ==
							MWIFIEX_MAX_TXRX_BD) {
			card->rxbd_rdptr = ((card->rxbd_rdptr &
					     MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
					    MWIFIEX_BD_FLAG_ROLLOVER_IND);
		}
		dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
			card->rxbd_rdptr, wrptr);

		/* Write the RX ring read pointer in to REG_RXBD_RDPTR */
		if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR,
				      card->rxbd_rdptr)) {
			dev_err(adapter->dev,
				"RECV DATA: failed to write REG_RXBD_RDPTR\n");
			ret = -1;
			goto done;
		}

		/* Read the RX ring Write pointer set by firmware */
		if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
			dev_err(adapter->dev,
				"RECV DATA: failed to read REG_TXBD_RDPTR\n");
			ret = -1;
			goto done;
		}
		dev_dbg(adapter->dev,
			"info: RECV DATA: Rcvd packet from fw successfully\n");
		mwifiex_handle_rx_packet(adapter, skb_tmp);
	}

done:
	if (ret && skb_tmp)
		dev_kfree_skb_any(skb_tmp);
	return ret;
}

/*
 * This function downloads the boot command to device
 */
static int
mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
{
	phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb);

	if (!(skb->data && skb->len && *buf_pa)) {
		dev_err(adapter->dev,
			"Invalid parameter in %s <%p, %#x:%x, %x>\n",
			__func__, skb->data, skb->len,
			(u32)*buf_pa, (u32)((u64)*buf_pa >> 32));
		return -1;
	}

	/* Write the lower 32bits of the physical address to scratch
	 * register 0 */
	if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) {
		dev_err(adapter->dev,
			"%s: failed to write download command to boot code.\n",
			__func__);
		return -1;
	}

	/* Write the upper 32bits of the physical address to scratch
	 * register 1 */
	if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG,
			      (u32)((u64)*buf_pa >> 32))) {
		dev_err(adapter->dev,
			"%s: failed to write download command to boot code.\n",
			__func__);
		return -1;
	}

	/* Write the command length to scratch register 2 */
	if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) {
		dev_err(adapter->dev,
			"%s: failed to write command len to scratch reg 2\n",
			__func__);
		return -1;
	}

	/* Ring the door bell */
	if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
			      CPU_INTR_DOOR_BELL)) {
		dev_err(adapter->dev,
			"%s: failed to assert door-bell intr\n", __func__);
		return -1;
	}

	return 0;
}

/*
 * This function downloads commands to the device
 */
static int
mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
{
	struct pcie_service_card *card = adapter->card;
	int ret = 0;
	phys_addr_t *cmd_buf_pa;
	phys_addr_t *cmdrsp_buf_pa;

	if (!(skb->data && skb->len)) {
		dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
			__func__, skb->data, skb->len);
		return -1;
	}

	/* Make sure a command response buffer is available */
	if (!card->cmdrsp_buf) {
		dev_err(adapter->dev,
			"No response buffer available, send command failed\n");
		return -EBUSY;
	}

	/* Make sure a command buffer is available */
	if (!card->cmd_buf) {
		dev_err(adapter->dev, "Command buffer not available\n");
		return -EBUSY;
	}

	adapter->cmd_sent = true;
	/* Copy the given skb in to DMA accessable shared buffer */
	skb_put(card->cmd_buf, MWIFIEX_SIZE_OF_CMD_BUFFER - card->cmd_buf->len);
	skb_trim(card->cmd_buf, skb->len);
	memcpy(card->cmd_buf->data, skb->data, skb->len);

	/* To send a command, the driver will:
		1. Write the 64bit physical address of the data buffer to
		   SCRATCH1 + SCRATCH0
		2. Ring the door bell (i.e. set the door bell interrupt)

		In response to door bell interrupt, the firmware will perform
		the DMA of the command packet (first header to obtain the total
		length and then rest of the command).
	*/

	if (card->cmdrsp_buf) {
		cmdrsp_buf_pa = MWIFIEX_SKB_PACB(card->cmdrsp_buf);
		/* Write the lower 32bits of the cmdrsp buffer physical
		   address */
		if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO,
				      (u32)*cmdrsp_buf_pa)) {
			dev_err(adapter->dev,
				"Failed to write download cmd to boot code.\n");
			ret = -1;
			goto done;
		}
		/* Write the upper 32bits of the cmdrsp buffer physical
		   address */
		if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI,
				      (u32)((u64)*cmdrsp_buf_pa >> 32))) {
			dev_err(adapter->dev,
				"Failed to write download cmd to boot code.\n");
			ret = -1;
			goto done;
		}
	}

	cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf);
	/* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */
	if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)*cmd_buf_pa)) {
		dev_err(adapter->dev,
			"Failed to write download cmd to boot code.\n");
		ret = -1;
		goto done;
	}
	/* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */
	if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI,
			      (u32)((u64)*cmd_buf_pa >> 32))) {
		dev_err(adapter->dev,
			"Failed to write download cmd to boot code.\n");
		ret = -1;
		goto done;
	}

	/* Write the command length to REG_CMD_SIZE */
	if (mwifiex_write_reg(adapter, REG_CMD_SIZE, card->cmd_buf->len)) {
		dev_err(adapter->dev,
			"Failed to write cmd len to REG_CMD_SIZE\n");
		ret = -1;
		goto done;
	}

	/* Ring the door bell */
	if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
			      CPU_INTR_DOOR_BELL)) {
		dev_err(adapter->dev,
			"Failed to assert door-bell intr\n");
		ret = -1;
		goto done;
	}

done:
	if (ret)
		adapter->cmd_sent = false;

	return 0;
}

/*
 * This function handles command complete interrupt
 */
static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct sk_buff *skb = card->cmdrsp_buf;
	int count = 0;

	dev_dbg(adapter->dev, "info: Rx CMD Response\n");

	if (!adapter->curr_cmd) {
		skb_pull(skb, INTF_HEADER_LEN);
		if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
			mwifiex_process_sleep_confirm_resp(adapter, skb->data,
							   skb->len);
			while (mwifiex_pcie_ok_to_access_hw(adapter) &&
							(count++ < 10))
				usleep_range(50, 60);
		} else {
			dev_err(adapter->dev,
				"There is no command but got cmdrsp\n");
		}
		memcpy(adapter->upld_buf, skb->data,
		       min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
		skb_push(skb, INTF_HEADER_LEN);
	} else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
		skb_pull(skb, INTF_HEADER_LEN);
		adapter->curr_cmd->resp_skb = skb;
		adapter->cmd_resp_received = true;
		/* Take the pointer and set it to CMD node and will
		   return in the response complete callback */
		card->cmdrsp_buf = NULL;

		/* Clear the cmd-rsp buffer address in scratch registers. This
		   will prevent firmware from writing to the same response
		   buffer again. */
		if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) {
			dev_err(adapter->dev,
				"cmd_done: failed to clear cmd_rsp_addr_lo\n");
			return -1;
		}
		/* Write the upper 32bits of the cmdrsp buffer physical
		   address */
		if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) {
			dev_err(adapter->dev,
				"cmd_done: failed to clear cmd_rsp_addr_hi\n");
			return -1;
		}
	}

	return 0;
}

/*
 * Command Response processing complete handler
 */
static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter,
					struct sk_buff *skb)
{
	struct pcie_service_card *card = adapter->card;

	if (skb) {
		card->cmdrsp_buf = skb;
		skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
	}

	return 0;
}

/*
 * This function handles firmware event ready interrupt
 */
static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
	u32 wrptr, event;

	if (adapter->event_received) {
		dev_dbg(adapter->dev, "info: Event being processed, "
			"do not process this interrupt just yet\n");
		return 0;
	}

	if (rdptr >= MWIFIEX_MAX_EVT_BD) {
		dev_dbg(adapter->dev, "info: Invalid read pointer...\n");
		return -1;
	}

	/* Read the event ring write pointer set by firmware */
	if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) {
		dev_err(adapter->dev,
			"EventReady: failed to read REG_EVTBD_WRPTR\n");
		return -1;
	}

	dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
		card->evtbd_rdptr, wrptr);
	if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
					      & MWIFIEX_EVTBD_MASK)) ||
	    ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) ==
	     (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
		struct sk_buff *skb_cmd;
		__le16 data_len = 0;
		u16 evt_len;

		dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr);
		skb_cmd = card->evt_buf_list[rdptr];
		/* Take the pointer and set it to event pointer in adapter
		   and will return back after event handling callback */
		card->evt_buf_list[rdptr] = NULL;
		card->evtbd_ring[rdptr]->paddr = 0;
		card->evtbd_ring[rdptr]->len = 0;
		card->evtbd_ring[rdptr]->flags = 0;

		event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN];
		adapter->event_cause = event;
		/* The first 4bytes will be the event transfer header
		   len is 2 bytes followed by type which is 2 bytes */
		memcpy(&data_len, skb_cmd->data, sizeof(__le16));
		evt_len = le16_to_cpu(data_len);

		skb_pull(skb_cmd, INTF_HEADER_LEN);
		dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len);

		if ((evt_len > 0) && (evt_len  < MAX_EVENT_SIZE))
			memcpy(adapter->event_body, skb_cmd->data +
			       MWIFIEX_EVENT_HEADER_LEN, evt_len -
			       MWIFIEX_EVENT_HEADER_LEN);

		adapter->event_received = true;
		adapter->event_skb = skb_cmd;

		/* Do not update the event read pointer here, wait till the
		   buffer is released. This is just to make things simpler,
		   we need to find a better method of managing these buffers.
		*/
	}

	return 0;
}

/*
 * Event processing complete handler
 */
static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
				       struct sk_buff *skb)
{
	struct pcie_service_card *card = adapter->card;
	int ret = 0;
	u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK;
	u32 wrptr;
	phys_addr_t *buf_pa;

	if (!skb)
		return 0;

	if (rdptr >= MWIFIEX_MAX_EVT_BD) {
		dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
			rdptr);
		return -EINVAL;
	}

	/* Read the event ring write pointer set by firmware */
	if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) {
		dev_err(adapter->dev,
			"event_complete: failed to read REG_EVTBD_WRPTR\n");
		return -1;
	}

	if (!card->evt_buf_list[rdptr]) {
		skb_push(skb, INTF_HEADER_LEN);
		card->evt_buf_list[rdptr] = skb;
		buf_pa = MWIFIEX_SKB_PACB(skb);
		card->evtbd_ring[rdptr]->paddr = *buf_pa;
		card->evtbd_ring[rdptr]->len = (u16)skb->len;
		card->evtbd_ring[rdptr]->flags = 0;
		skb = NULL;
	} else {
		dev_dbg(adapter->dev,
			"info: ERROR: buf still valid at index %d, <%p, %p>\n",
			rdptr, card->evt_buf_list[rdptr], skb);
	}

	if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
		card->evtbd_rdptr = ((card->evtbd_rdptr &
					MWIFIEX_BD_FLAG_ROLLOVER_IND) ^
					MWIFIEX_BD_FLAG_ROLLOVER_IND);
	}

	dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
		card->evtbd_rdptr, wrptr);

	/* Write the event ring read pointer in to REG_EVTBD_RDPTR */
	if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) {
		dev_err(adapter->dev,
			"event_complete: failed to read REG_EVTBD_RDPTR\n");
		return -1;
	}

	dev_dbg(adapter->dev, "info: Check Events Again\n");
	ret = mwifiex_pcie_process_event_ready(adapter);

	return ret;
}

/*
 * This function downloads the firmware to the card.
 *
 * Firmware is downloaded to the card in blocks. Every block download
 * is tested for CRC errors, and retried a number of times before
 * returning failure.
 */
static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
				    struct mwifiex_fw_image *fw)
{
	int ret;
	u8 *firmware = fw->fw_buf;
	u32 firmware_len = fw->fw_len;
	u32 offset = 0;
	struct sk_buff *skb;
	u32 txlen, tx_blocks = 0, tries, len;
	u32 block_retry_cnt = 0;

	if (!adapter) {
		pr_err("adapter structure is not valid\n");
		return -1;
	}

	if (!firmware || !firmware_len) {
		dev_err(adapter->dev,
			"No firmware image found! Terminating download\n");
		return -1;
	}

	dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
		firmware_len);

	if (mwifiex_pcie_disable_host_int(adapter)) {
		dev_err(adapter->dev,
			"%s: Disabling interrupts failed.\n", __func__);
		return -1;
	}

	skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
	if (!skb) {
		ret = -ENOMEM;
		goto done;
	}
	mwifiex_update_sk_buff_pa(skb);

	/* Perform firmware data transfer */
	do {
		u32 ireg_intr = 0;

		/* More data? */
		if (offset >= firmware_len)
			break;

		for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
			ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG,
					       &len);
			if (ret) {
				dev_warn(adapter->dev,
					 "Failed reading len from boot code\n");
				goto done;
			}
			if (len)
				break;
			usleep_range(10, 20);
		}

		if (!len) {
			break;
		} else if (len > MWIFIEX_UPLD_SIZE) {
			pr_err("FW download failure @ %d, invalid length %d\n",
			       offset, len);
			ret = -1;
			goto done;
		}

		txlen = len;

		if (len & BIT(0)) {
			block_retry_cnt++;
			if (block_retry_cnt > MAX_WRITE_IOMEM_RETRY) {
				pr_err("FW download failure @ %d, over max "
				       "retry count\n", offset);
				ret = -1;
				goto done;
			}
			dev_err(adapter->dev, "FW CRC error indicated by the "
				"helper: len = 0x%04X, txlen = %d\n",
				len, txlen);
			len &= ~BIT(0);
			/* Setting this to 0 to resend from same offset */
			txlen = 0;
		} else {
			block_retry_cnt = 0;
			/* Set blocksize to transfer - checking for
			   last block */
			if (firmware_len - offset < txlen)
				txlen = firmware_len - offset;

			dev_dbg(adapter->dev, ".");

			tx_blocks = (txlen +
				     MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) /
				     MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD;

			/* Copy payload to buffer */
			memmove(skb->data, &firmware[offset], txlen);
		}

		skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
		skb_trim(skb, tx_blocks * MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD);

		/* Send the boot command to device */
		if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
			dev_err(adapter->dev,
				"Failed to send firmware download command\n");
			ret = -1;
			goto done;
		}
		/* Wait for the command done interrupt */
		do {
			if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
					     &ireg_intr)) {
				dev_err(adapter->dev, "%s: Failed to read "
					"interrupt status during fw dnld.\n",
					__func__);
				ret = -1;
				goto done;
			}
		} while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
			 CPU_INTR_DOOR_BELL);
		offset += txlen;
	} while (true);

	dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
		offset);

	ret = 0;

done:
	dev_kfree_skb_any(skb);
	return ret;
}

/*
 * This function checks the firmware status in card.
 *
 * The winner interface is also determined by this function.
 */
static int
mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
{
	int ret = 0;
	u32 firmware_stat, winner_status;
	u32 tries;

	/* Mask spurios interrupts */
	if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
			      HOST_INTR_MASK)) {
		dev_warn(adapter->dev, "Write register failed\n");
		return -1;
	}

	dev_dbg(adapter->dev, "Setting driver ready signature\n");
	if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) {
		dev_err(adapter->dev,
			"Failed to write driver ready signature\n");
		return -1;
	}

	/* Wait for firmware initialization event */
	for (tries = 0; tries < poll_num; tries++) {
		if (mwifiex_read_reg(adapter, PCIE_SCRATCH_3_REG,
				     &firmware_stat))
			ret = -1;
		else
			ret = 0;
		if (ret)
			continue;
		if (firmware_stat == FIRMWARE_READY_PCIE) {
			ret = 0;
			break;
		} else {
			mdelay(100);
			ret = -1;
		}
	}

	if (ret) {
		if (mwifiex_read_reg(adapter, PCIE_SCRATCH_3_REG,
				     &winner_status))
			ret = -1;
		else if (!winner_status) {
			dev_err(adapter->dev, "PCI-E is the winner\n");
			adapter->winner = 1;
			ret = -1;
		} else {
			dev_err(adapter->dev,
				"PCI-E is not the winner <%#x,%d>, exit dnld\n",
				ret, adapter->winner);
			ret = 0;
		}
	}

	return ret;
}

/*
 * This function reads the interrupt status from card.
 */
static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
{
	u32 pcie_ireg;
	unsigned long flags;

	if (!mwifiex_pcie_ok_to_access_hw(adapter))
		return;

	if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) {
		dev_warn(adapter->dev, "Read register failed\n");
		return;
	}

	if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {

		mwifiex_pcie_disable_host_int(adapter);

		/* Clear the pending interrupts */
		if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS,
				      ~pcie_ireg)) {
			dev_warn(adapter->dev, "Write register failed\n");
			return;
		}
		spin_lock_irqsave(&adapter->int_lock, flags);
		adapter->int_status |= pcie_ireg;
		spin_unlock_irqrestore(&adapter->int_lock, flags);

		if (pcie_ireg & HOST_INTR_CMD_DONE) {
			if ((adapter->ps_state == PS_STATE_SLEEP_CFM) ||
			    (adapter->ps_state == PS_STATE_SLEEP)) {
				mwifiex_pcie_enable_host_int(adapter);
				if (mwifiex_write_reg(adapter,
						      PCIE_CPU_INT_EVENT,
						      CPU_INTR_SLEEP_CFM_DONE)
						      ) {
					dev_warn(adapter->dev,
						 "Write register failed\n");
					return;

				}
			}
		} else if (!adapter->pps_uapsd_mode &&
			   adapter->ps_state == PS_STATE_SLEEP) {
				/* Potentially for PCIe we could get other
				 * interrupts like shared. Don't change power
				 * state until cookie is set */
				if (mwifiex_pcie_ok_to_access_hw(adapter))
					adapter->ps_state = PS_STATE_AWAKE;
		}
	}
}

/*
 * Interrupt handler for PCIe root port
 *
 * This function reads the interrupt status from firmware and assigns
 * the main process in workqueue which will handle the interrupt.
 */
static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
{
	struct pci_dev *pdev = (struct pci_dev *)context;
	struct pcie_service_card *card;
	struct mwifiex_adapter *adapter;

	if (!pdev) {
		pr_debug("info: %s: pdev is NULL\n", (u8 *)pdev);
		goto exit;
	}

	card = (struct pcie_service_card *) pci_get_drvdata(pdev);
	if (!card || !card->adapter) {
		pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
			 card ? card->adapter : NULL);
		goto exit;
	}
	adapter = card->adapter;

	if (adapter->surprise_removed)
		goto exit;

	mwifiex_interrupt_status(adapter);
	queue_work(adapter->workqueue, &adapter->main_work);

exit:
	return IRQ_HANDLED;
}

/*
 * This function checks the current interrupt status.
 *
 * The following interrupts are checked and handled by this function -
 *      - Data sent
 *      - Command sent
 *      - Command received
 *      - Packets received
 *      - Events received
 *
 * In case of Rx packets received, the packets are uploaded from card to
 * host and processed accordingly.
 */
static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
{
	int ret;
	u32 pcie_ireg = 0;
	unsigned long flags;

	spin_lock_irqsave(&adapter->int_lock, flags);
	/* Clear out unused interrupts */
	adapter->int_status &= HOST_INTR_MASK;
	spin_unlock_irqrestore(&adapter->int_lock, flags);

	while (adapter->int_status & HOST_INTR_MASK) {
		if (adapter->int_status & HOST_INTR_DNLD_DONE) {
			adapter->int_status &= ~HOST_INTR_DNLD_DONE;
			if (adapter->data_sent) {
				dev_dbg(adapter->dev, "info: DATA sent intr\n");
				adapter->data_sent = false;
			}
		}
		if (adapter->int_status & HOST_INTR_UPLD_RDY) {
			adapter->int_status &= ~HOST_INTR_UPLD_RDY;
			dev_dbg(adapter->dev, "info: Rx DATA\n");
			ret = mwifiex_pcie_process_recv_data(adapter);
			if (ret)
				return ret;
		}
		if (adapter->int_status & HOST_INTR_EVENT_RDY) {
			adapter->int_status &= ~HOST_INTR_EVENT_RDY;
			dev_dbg(adapter->dev, "info: Rx EVENT\n");
			ret = mwifiex_pcie_process_event_ready(adapter);
			if (ret)
				return ret;
		}

		if (adapter->int_status & HOST_INTR_CMD_DONE) {
			adapter->int_status &= ~HOST_INTR_CMD_DONE;
			if (adapter->cmd_sent) {
				dev_dbg(adapter->dev,
					"info: CMD sent Interrupt\n");
				adapter->cmd_sent = false;
			}
			/* Handle command response */
			ret = mwifiex_pcie_process_cmd_complete(adapter);
			if (ret)
				return ret;
		}

		if (mwifiex_pcie_ok_to_access_hw(adapter)) {
			if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
					     &pcie_ireg)) {
				dev_warn(adapter->dev,
					 "Read register failed\n");
				return -1;
			}

			if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
				if (mwifiex_write_reg(adapter,
						      PCIE_HOST_INT_STATUS,
						      ~pcie_ireg)) {
					dev_warn(adapter->dev,
						 "Write register failed\n");
					return -1;
				}
				adapter->int_status |= pcie_ireg;
				adapter->int_status &= HOST_INTR_MASK;
			}

		}
	}
	dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
		adapter->cmd_sent, adapter->data_sent);
	mwifiex_pcie_enable_host_int(adapter);

	return 0;
}

/*
 * This function downloads data from driver to card.
 *
 * Both commands and data packets are transferred to the card by this
 * function.
 *
 * This function adds the PCIE specific header to the front of the buffer
 * before transferring. The header contains the length of the packet and
 * the type. The firmware handles the packets based upon this set type.
 */
static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
				     struct sk_buff *skb,
				     struct mwifiex_tx_param *tx_param)
{
	if (!skb) {
		dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__);
		return -1;
	}

	if (type == MWIFIEX_TYPE_DATA)
		return mwifiex_pcie_send_data(adapter, skb);
	else if (type == MWIFIEX_TYPE_CMD)
		return mwifiex_pcie_send_cmd(adapter, skb);

	return 0;
}

/*
 * This function initializes the PCI-E host memory space, WCB rings, etc.
 *
 * The following initializations steps are followed -
 *      - Allocate TXBD ring buffers
 *      - Allocate RXBD ring buffers
 *      - Allocate event BD ring buffers
 *      - Allocate command response ring buffer
 *      - Allocate sleep cookie buffer
 */
static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	int ret;
	struct pci_dev *pdev = card->dev;

	pci_set_drvdata(pdev, card);

	ret = pci_enable_device(pdev);
	if (ret)
		goto err_enable_dev;

	pci_set_master(pdev);

	dev_dbg(adapter->dev, "try set_consistent_dma_mask(32)\n");
	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
	if (ret) {
		dev_err(adapter->dev, "set_dma_mask(32) failed\n");
		goto err_set_dma_mask;
	}

	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
	if (ret) {
		dev_err(adapter->dev, "set_consistent_dma_mask(64) failed\n");
		goto err_set_dma_mask;
	}

	ret = pci_request_region(pdev, 0, DRV_NAME);
	if (ret) {
		dev_err(adapter->dev, "req_reg(0) error\n");
		goto err_req_region0;
	}
	card->pci_mmap = pci_iomap(pdev, 0, 0);
	if (!card->pci_mmap) {
		dev_err(adapter->dev, "iomap(0) error\n");
		goto err_iomap0;
	}
	ret = pci_request_region(pdev, 2, DRV_NAME);
	if (ret) {
		dev_err(adapter->dev, "req_reg(2) error\n");
		goto err_req_region2;
	}
	card->pci_mmap1 = pci_iomap(pdev, 2, 0);
	if (!card->pci_mmap1) {
		dev_err(adapter->dev, "iomap(2) error\n");
		goto err_iomap2;
	}

	dev_dbg(adapter->dev,
		"PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
		card->pci_mmap, card->pci_mmap1);

	card->cmdrsp_buf = NULL;
	ret = mwifiex_pcie_create_txbd_ring(adapter);
	if (ret)
		goto err_cre_txbd;
	ret = mwifiex_pcie_create_rxbd_ring(adapter);
	if (ret)
		goto err_cre_rxbd;
	ret = mwifiex_pcie_create_evtbd_ring(adapter);
	if (ret)
		goto err_cre_evtbd;
	ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter);
	if (ret)
		goto err_alloc_cmdbuf;
	ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter);
	if (ret)
		goto err_alloc_cookie;

	return ret;

err_alloc_cookie:
	mwifiex_pcie_delete_cmdrsp_buf(adapter);
err_alloc_cmdbuf:
	mwifiex_pcie_delete_evtbd_ring(adapter);
err_cre_evtbd:
	mwifiex_pcie_delete_rxbd_ring(adapter);
err_cre_rxbd:
	mwifiex_pcie_delete_txbd_ring(adapter);
err_cre_txbd:
	pci_iounmap(pdev, card->pci_mmap1);
err_iomap2:
	pci_release_region(pdev, 2);
err_req_region2:
	pci_iounmap(pdev, card->pci_mmap);
err_iomap0:
	pci_release_region(pdev, 0);
err_req_region0:
err_set_dma_mask:
	pci_disable_device(pdev);
err_enable_dev:
	pci_set_drvdata(pdev, NULL);
	return ret;
}

/*
 * This function cleans up the allocated card buffers.
 *
 * The following are freed by this function -
 *      - TXBD ring buffers
 *      - RXBD ring buffers
 *      - Event BD ring buffers
 *      - Command response ring buffer
 *      - Sleep cookie buffer
 */
static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;
	struct pci_dev *pdev = card->dev;

	mwifiex_pcie_delete_sleep_cookie_buf(adapter);
	mwifiex_pcie_delete_cmdrsp_buf(adapter);
	mwifiex_pcie_delete_evtbd_ring(adapter);
	mwifiex_pcie_delete_rxbd_ring(adapter);
	mwifiex_pcie_delete_txbd_ring(adapter);
	card->cmdrsp_buf = NULL;

	dev_dbg(adapter->dev, "Clearing driver ready signature\n");
	if (user_rmmod) {
		if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000))
			dev_err(adapter->dev,
				"Failed to write driver not-ready signature\n");
	}

	if (pdev) {
		pci_iounmap(pdev, card->pci_mmap);
		pci_iounmap(pdev, card->pci_mmap1);

		pci_release_regions(pdev);
		pci_disable_device(pdev);
		pci_set_drvdata(pdev, NULL);
	}
}

/*
 * This function registers the PCIE device.
 *
 * PCIE IRQ is claimed, block size is set and driver data is initialized.
 */
static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
{
	int ret;
	struct pcie_service_card *card = adapter->card;
	struct pci_dev *pdev = card->dev;

	/* save adapter pointer in card */
	card->adapter = adapter;

	ret = request_irq(pdev->irq, mwifiex_pcie_interrupt, IRQF_SHARED,
			  "MRVL_PCIE", pdev);
	if (ret) {
		pr_err("request_irq failed: ret=%d\n", ret);
		adapter->card = NULL;
		return -1;
	}

	adapter->dev = &pdev->dev;
	strcpy(adapter->fw_name, PCIE8766_DEFAULT_FW_NAME);

	return 0;
}

/*
 * This function unregisters the PCIE device.
 *
 * The PCIE IRQ is released, the function is disabled and driver
 * data is set to null.
 */
static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
{
	struct pcie_service_card *card = adapter->card;

	if (card) {
		dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__);
		free_irq(card->dev->irq, card->dev);
	}
}

static struct mwifiex_if_ops pcie_ops = {
	.init_if =			mwifiex_pcie_init,
	.cleanup_if =			mwifiex_pcie_cleanup,
	.check_fw_status =		mwifiex_check_fw_status,
	.prog_fw =			mwifiex_prog_fw_w_helper,
	.register_dev =			mwifiex_register_dev,
	.unregister_dev =		mwifiex_unregister_dev,
	.enable_int =			mwifiex_pcie_enable_host_int,
	.process_int_status =		mwifiex_process_int_status,
	.host_to_card =			mwifiex_pcie_host_to_card,
	.wakeup =			mwifiex_pm_wakeup_card,
	.wakeup_complete =		mwifiex_pm_wakeup_card_complete,

	/* PCIE specific */
	.cmdrsp_complete =		mwifiex_pcie_cmdrsp_complete,
	.event_complete =		mwifiex_pcie_event_complete,
	.update_mp_end_port =		NULL,
	.cleanup_mpa_buf =		NULL,
};

/*
 * This function initializes the PCIE driver module.
 *
 * This initiates the semaphore and registers the device with
 * PCIE bus.
 */
static int mwifiex_pcie_init_module(void)
{
	int ret;

	pr_debug("Marvell 8766 PCIe Driver\n");

	sema_init(&add_remove_card_sem, 1);

	/* Clear the flag in case user removes the card. */
	user_rmmod = 0;

	ret = pci_register_driver(&mwifiex_pcie);
	if (ret)
		pr_err("Driver register failed!\n");
	else
		pr_debug("info: Driver registered successfully!\n");

	return ret;
}

/*
 * This function cleans up the PCIE driver.
 *
 * The following major steps are followed for cleanup -
 *      - Resume the device if its suspended
 *      - Disconnect the device if connected
 *      - Shutdown the firmware
 *      - Unregister the device from PCIE bus.
 */
static void mwifiex_pcie_cleanup_module(void)
{
	if (!down_interruptible(&add_remove_card_sem))
		up(&add_remove_card_sem);

	/* Set the flag as user is removing this module. */
	user_rmmod = 1;

	pci_unregister_driver(&mwifiex_pcie);
}

module_init(mwifiex_pcie_init_module);
module_exit(mwifiex_pcie_cleanup_module);

MODULE_AUTHOR("Marvell International Ltd.");
MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
MODULE_VERSION(PCIE_VERSION);
MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE("mrvl/pcie8766_uapsta.bin");


text:
"""
swaggerconformance documentation build configuration file.

This file is execfile()d with the current directory set to its
containing dir.

All configuration values have a default; values that are commented out
serve to show the default.
"""
# pylint: disable=C0103

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
import os
import sys
sys.path.insert(0, os.path.abspath('../../'))

import shutil
from recommonmark.parser import CommonMarkParser

# Put other docs files into this source location.
shutil.copyfile('../../readme.md', 'readme.md')
shutil.copyfile('../../examples/readme.md', 'examples.md')

# -- General configuration ------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#
needs_sphinx = '1.7'

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.autodoc',
              'sphinx.ext.intersphinx',
              'sphinx.ext.viewcode']

# Add any paths that contain templates here, relative to this directory.
templates_path = []

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = ['.rst', '.md']

# Support markdown docs.
source_parsers = {
    '.md': CommonMarkParser,
}

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = 'swaggerconformance'
copyright = '2017, olipratt'
author = 'olipratt'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.2.5'
# The full version, including alpha/beta/rc tags.
release = version

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False

# Don't warn about links to remote images.
suppress_warnings = ["image.nonlocal_uri"]

# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'

# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}

# Don't show a link to the page source on each HTML page.
html_show_sourcelink = False
# Don't generate a module index as there aren't enough modules to need one.
html_domain_indices = False
# Whether to generate an index - which needs manually referencing.
html_use_index = True

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = []

# -- Options for HTMLHelp output ------------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = 'swaggerconformancedoc'

# -- Options for LaTeX output ---------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #
    # 'papersize': 'letterpaper',

    # The font size ('10pt', '11pt' or '12pt').
    #
    # 'pointsize': '10pt',

    # Additional stuff for the LaTeX preamble.
    #
    # 'preamble': '',

    # Latex figure (float) alignment
    #
    # 'figure_align': 'htbp',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
#  author, documentclass [howto, manual, or own class]).
latex_documents = [
    (master_doc, 'swaggerconformance.tex', 'swaggerconformance Documentation',
     'olipratt', 'manual'),
]

# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    (master_doc, 'swaggerconformance', 'swaggerconformance Documentation',
     [author], 1)
]

# -- Options for Texinfo output -------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    (master_doc, 'swaggerconformance', 'swaggerconformance Documentation',
     author, 'swaggerconformance', 'One line description of project.',
     'Miscellaneous'),
]

# References to other documentation for intersphinx to link to - typically the
# standard library plus any dependent 3rd party libraries.
intersphinx_mapping = {'https://docs.python.org/3': None,
                       # 'http://hypothesis.readthedocs.io/en/latest/': None,
                       'http://pyswagger.readthedocs.io/en/latest/': None}

# The name of a reST role (builtin or Sphinx extension) to use as the default
# role, that is, for text marked up `like this`. 'py:obj' means 'some python
# object of unspecified type' so that Sphinx will try and match it to some
# available class/function/constant/etc.
default_role = 'py:obj'

# Generate API documentation as part of the standard docs build.
def run_apidoc(_):
	from sphinx.ext.apidoc import main
	import os
	import sys
	cur_dir = os.path.abspath(os.path.dirname(__file__))
	package_dir = os.path.join(cur_dir, "../..", project)
	api_out_dir = os.path.join(cur_dir, "modules")
	main(['--separate', '--force', '--no-toc', '-o', api_out_dir, package_dir])

def setup(app):
	app.connect('builder-inited', run_apidoc)

redpajama_set_name: RedPajamaGithub


text:
source tests/test-helpers.sh

THIS=$0
SCRIPT=${THIS%.sh}.tcl
OUTPUT=${THIS%.sh}.out

source $( dirname $0 )/setup.sh > ${OUTPUT} 2>&1

PROCS=3
export TURBINE_COASTER_WORKERS=1

COASTER_SVC=coaster-service
SVC_CONF="$(dirname $0)/coaster-exec-local.conf"

#TODO: assumes coaster-service on path
if ! which $COASTER_SVC &> /dev/null ; then
  echo "${COASTER_SVC} not on path"
  exit 1
fi

source "${SVC_CONF}"
"${COASTER_SVC}" -nosec -port ${SERVICE_PORT} &
COASTER_SVC_PID=$!

# Reduce heartbeat interval to catch bugs in heartbeat
export COASTER_HEARTBEAT_INTERVAL=1

export TURBINE_COASTER_CONFIG="jobManager=local,maxParallelTasks=64"
TURBINE_COASTER_CONFIG+=",coasterServiceURL=127.0.0.1:53363"

# Delay to allow service to start up
sleep 0.5

if bin/turbine -l -n ${PROCS} ${SCRIPT} >> ${OUTPUT} 2>&1
then
  TURBINE_RC=0
else
  TURBINE_RC=$?
  echo "TURBINE FAILED: ${TURBINE_RC}"
fi

echo "Killing service ${COASTER_SVC_PID} and immediate children"
for child_pid in $(ps -ef| awk '$3 == '${COASTER_SVC_PID}' { print $2 }')
do
  echo "Killing process $pid"
  kill $child_pid
done

kill ${COASTER_SVC_PID}
wait || true

[[ ${TURBINE_RC} == 0 ]] || test_result 1

grep -q "WAITING WORK" ${OUTPUT} && test_result 1

coaster_exp=100
coaster_count=$(grep -q -c -F "COASTER task output set:" ${OUTPUT})
if [ "$coaster_count" -ne "$coaster_exp" ]
then
  echo "Coaster tasks: expected $coaster_act actual $coaster_count"
  exit 1
fi

test_result 0


text:
define(function() {

  "use strict";

  function GoogleAnalytics(selectors) {
    for (var selector in selectors) {
      this[selector] = selectors[selector];
    }
  }

  GoogleAnalytics.prototype.track = function() {

    if (!(window.lp.analytics.api && window.lp.analytics.api.trackEvent)) {
      return;
    }

    window.lp.analytics.api.trackEvent({
      category: "car-rental",
      action:   "search-partner-click",
      params: {
        locationStart:     this.$locationStart.val(),
        locationEnd:       this.$locationEnd.val(),
        startDate:         this.$dateStart.val() + "," + this.$timeStart.val(),
        endDate:           this.$dateEnd.val() + "," + this.$timeEnd.val(),
        locationResidence: this.$locationResidence.val()
      }
    });

  };

  return GoogleAnalytics;

});


text:
import Translator from '../../src/Translator';
import ResourceStore from '../../src/ResourceStore.js';
import LanguageUtils from '../../src/LanguageUtils';
import PluralResolver from '../../src/PluralResolver';
import Interpolator from '../../src/Interpolator';

describe('Translator', () => {
  describe('translate() un/escape', () => {
    var t;

    before(() => {
      const rs = new ResourceStore({
        en: {
          translation: {
            test: 'text {{var}}',
          },
        },
      });
      const lu = new LanguageUtils({ fallbackLng: 'en' });
      t = new Translator(
        {
          resourceStore: rs,
          languageUtils: lu,
          pluralResolver: new PluralResolver(lu, { prepend: '_', simplifyPluralSuffix: true }),
          interpolator: new Interpolator(),
        },
        {
          defaultNS: 'translation',
          ns: 'translation',
          interpolation: {
            interpolateResult: true,
            interpolateDefaultValue: true,
            interpolateKey: true,
            escapeValue: true,
          },
        },
      );
      t.changeLanguage('en');
    });

    var tests = [
      { args: ['translation:test', { var: 'a&b' }], expected: 'text a&b' },
      {
        args: ['translation:test', { var: 'a&b', interpolation: { escapeValue: false } }],
        expected: 'text a&b',
      },
      { args: ['translation:test', { var: ['a', 'b'] }], expected: 'text a,b' },
      {
        args: [
          'translation:test',
          {
            var: ['a', 'b'],
            interpolation: { useRawValueToEscape: true, escape: (value) => value.join('-') },
          },
        ],
        expected: 'text a-b',
      },
    ];

    tests.forEach((test) => {
      it('correctly translates for ' + JSON.stringify(test.args) + ' args', () => {
        expect(t.translate.apply(t, test.args)).to.eql(test.expected);
      });
    });
  });
});


text:
"""
Django models
"""
import datetime

from django.db import models
from django.db.models import Q
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from django.core import validators
from django.core.exceptions import ValidationError
from django.utils.translation import get_language_info

def money_field(*args, **kwargs):
    return models.DecimalField(max_digits=20, decimal_places=2, blank=False,
                               default=0, *args, **kwargs)

def today_is_the_day(weekday):
    return lambda: datetime.date().isoweekday() == weekday

def is_first_of_month(value):
    if not hasattr(value, "day") or not hasattr(value, "month") or \
            not hasattr(value, "year"):
        raise ValidationError(u"{} (type {}) is no date".format(value,
                                                                type(value)))
    if value.day != 1:
        raise ValidationError(u"{} is not the first of month".format(value))

def first_of_this_month():
    today = datetime.date.today()
    today = datetime.date(day=1, month=today.month, year=today.year)
    return today

class Currency(models.Model):
    code = models.CharField(max_length=3, primary_key=True)
    name = models.CharField(max_length=32, blank=False)
    symbol = models.CharField(max_length=5, blank=False)

    def __unicode__(self):
        return "{} ({})".format(sefl.name, self.code)

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name="budget_profile")
    language = models.CharField(max_length=2, choices=(
                                ("en", get_language_info("en")['name_local']),
                                ("de", get_language_info("de")['name_local'])),
                                default="en")

    def __unicode__(self):
        return self.user.username

    @property
    def total_accounts_sum(self):
        return sum(account.saldo for account in self.accounts.all())

    @property
    def budget_accounts(self):
        return self.accounts.filter(on_budget=True).order_by('name')

    @property
    def budget_accounts_sum(self):
        return sum(account.saldo for account in self.budget_accounts)

    @property
    def off_budget_accounts(self):
        return self.accounts.filter(on_budget=False).order_by('name')

    @property
    def off_budget_accounts_sum(self):
        return sum(account.saldo for account in self.off_budget_accounts)

class Account(models.Model):
    TYPE_CASH           =  0
    TYPE_CHECKING       =  1
    TYPE_CREDIT_CARD    =  2
    TYPE_INVESTMENT     =  3
    TYPE_LINE_OF_CREDIT =  4
    TYPE_LOAN           =  5
    TYPE_MERCHANT       =  6
    TYPE_MORTAGE        =  7
    TYPE_P2P_WALLET     =  8
    TYPE_PAYPAL         =  8
    TYPE_SAVING         =  9
    TYPE_OTHER          = 10

    name = models.CharField(max_length=32, blank=False)
    note = models.TextField(blank=True)
    user = models.ForeignKey(UserProfile, null=False, related_name="accounts")
    type = models.IntegerField(blank=False,
            choices=((TYPE_CASH, "Cash"), (TYPE_CHECKING, "Checking"),
            (TYPE_CREDIT_CARD, "Credit Card"),
            (TYPE_INVESTMENT, "Investment Account"), (TYPE_LINE_OF_CREDIT,
            "Line of Credit"), (TYPE_LOAN, "Loan"), (TYPE_MERCHANT,
            "Merchant Account"), (TYPE_MERCHANT, "Mortage"),
            (TYPE_P2P_WALLET, "Peer-to-peer electronic money wallet"),
            (TYPE_PAYPAL, "Paypal"), (TYPE_SAVING, "Saving"),
            (TYPE_OTHER, "Other")))
    line_of_credit = money_field()
    starting_balance = money_field()
    on_budget = models.BooleanField(default=True, blank=False)

    class Meta:
        unique_together = ('name','user')

    def __unicode__(self):
        return self.name

    @property
    def saldo(self):
        saldo = self.starting_balance
        transactions = self.implemented_transactions.aggregate(models.Sum('outflow'),
                                                               models.Sum('inflow'))
        saldo -= transactions['outflow__sum'] or 0
        saldo += transactions['inflow__sum'] or 0
        transfers_to = self.implemented_transfers_to.aggregate(models.Sum('outflow'),
                                                               models.Sum('inflow'))
        saldo += transfers_to['outflow__sum'] or 0
        saldo -= transfers_to['inflow__sum'] or 0
        return saldo

    @property
    def implemented_transactions(self):
        return self.transactions.exclude(
                Q(pk__in=ScheduledTransaction.objects.values_list('transaction_ptr_id',
                                                                  flat=True)) | \
                Q(pk__in=ScheduledTransfer.objects.values_list('transaction_ptr_id',
                                                               flat=True)))

    @property
    def implemented_transfers_to(self):
        return self.transfers_to.exclude(
                Q(pk__in=ScheduledTransfer.objects.values_list('transfer_ptr_id',
                                                               flat=True)))

class CategoryGroup(models.Model):
    name = models.CharField(max_length=32, blank=False, unique=True)
    user = models.ManyToManyField(UserProfile, related_name="category_groups")
    default = models.BooleanField(default=False, blank=False)
    budgeted = models.BooleanField(default=True, editable=False)

    def __unicode__(self):
        return u"{}".format(self.name)

class Category(models.Model):
    group = models.ForeignKey(CategoryGroup, null=False,
                              related_name="categories")
    user = models.ManyToManyField(UserProfile, related_name="categories")
    name = models.CharField(max_length=32, primary_key=True)
    default = models.BooleanField(default=False, blank=False)
    budgeted = models.BooleanField(default=True, editable=False)

    def __unicode__(self):
        return u"{}: {}".format(self.group, self.name)

class Budget(models.Model):
    month = models.DateField(validators=[is_first_of_month], blank=False,
                             default=first_of_this_month)
    category_amounts = models.ManyToManyField(Category, through="CategoryBudget",
                                              related_name="budgets")
    user = models.ForeignKey(UserProfile, blank=False, related_name="budgets")

    class Meta:
        unique_together = ('month', 'user')

    def __unicode__(self):
        return self.month.strftime("%B %Y")

    @property
    def amount(self):
        return self.category_budget_set.aggregate(models.Sum('amount'))

    def category_group_amount(self, category_group):
        return self.category_budget_set.filter(category__group=category_group).\
                aggregate(models.Sum('amount'))

class CategoryBudget(models.Model):
    budget = models.ForeignKey(Budget, blank=False)
    category = models.ForeignKey(Category, blank=False)
    amount = money_field(validators=[validators.MinValueValidator(0)])

    class Meta:
        unique_together = ('category', 'budget')

    def __unicode__(self):
        return u"0.02f".format(self.amount)

class Transaction(models.Model):
    added = models.DateTimeField(auto_now_add=True)
    account = models.ForeignKey(Account, null=False,
                                related_name="transactions")
    check_nr = models.IntegerField(null=True, blank=True)
    payee = models.CharField(max_length=32)
    date = models.DateField()
    category = models.ForeignKey(Category, related_name="transactions",
                                 null=True, blank=True)
    memo = models.CharField(max_length=64, null=True, blank=True)
    inflow = money_field(validators=[validators.MinValueValidator(0)])
    outflow = money_field(validators=[validators.MinValueValidator(0)])
    cleared = models.BooleanField(default=False, blank=False)

    def is_transfer(self):
        return Transfer.objects.filter(pk=self.pk).exists()

    def as_transfer(self):
        return Transfer.objects.get(pk=self.pk)

    def __unicode__(self):
        return u"Transaction : {} <=> {}".format(self.account, self.payee)

class Transfer(Transaction):
    to_account = models.ForeignKey(Account, null=True,
                                   related_name="transfers_to",
                                   on_delete=models.SET_NULL)

    def __unicode__(self):
        return u"Transfer : {} <=> {}".format(self.account, self.to_account)


text:
@implementation SamuraiRenderStoreNode

@def_prop_strong( SamuraiRenderObject *, target );

+ (SamuraiRenderStoreNode *)storeNode
{
	return [[self alloc] init];
}

+ (SamuraiRenderStoreNode *)storeNode:(SamuraiRenderObject *)object
{
	SamuraiRenderStoreNode * store = [[self alloc] init];
	store.target = object;
	return store;
}

#pragma mark -

- (id)init
{
	self = [super init];
	if ( self )
	{
	}
	return self;
}

- (void)dealloc
{
	self.target = nil;
}

#pragma mark -

- (NSArray *)find:(NSString *)dataPath
{
	if ( nil == dataPath )
		return nil;

	NSArray * subPaths = [dataPath componentsSeparatedByString:@"."];
	NSMutableArray * result = [NSMutableArray array];

	[self matchFirstOf:subPaths atIndex:0 toResult:result];

	return result;
}

- (BOOL)match:(NSString *)dataPath
{
	NSString * leftDataPath = self.target.dom.domName ?: self.target.dom.domTag;
	NSString * rightDataPath = dataPath;

	if ( [leftDataPath hasSuffix:@"[]"] )
	{
		leftDataPath = [leftDataPath substringToIndex:leftDataPath.length - 2];
	}

	if ( [rightDataPath hasSuffix:@"[]"] )
	{
		rightDataPath = [rightDataPath substringToIndex:rightDataPath.length - 2];
	}

	return [leftDataPath isEqualToString:rightDataPath];
}

- (void)matchFirstOf:(NSArray *)dataPaths atIndex:(NSUInteger)index toResult:(NSMutableArray *)result
{
	if ( [self match:[dataPaths objectAtIndex:index]] )
	{
		if ( (index + 1) >= dataPaths.count )
		{
			[result addObject:self];
		}
		else
		{
			for ( SamuraiRenderStoreNode * childStore in self.childs )
			{
				[childStore matchFirstOf:dataPaths atIndex:(index + 1) toResult:result];
			}
		}
	}
	else
	{
		for ( SamuraiRenderStoreNode * childStore in self.childs )
		{
			[childStore matchFirstOf:dataPaths atIndex:index toResult:result];
		}
	}
}

- (void)dump
{
#if __SAMURAI_DEBUG__

	if ( self.target && self.target.dom.domName )
	{
		PERF( @"<%@ name='%@'>", self.target.dom.domTag, self.target.dom.domName );

		[[SamuraiLogger sharedInstance] indent];
	}

	for ( SamuraiRenderObject * child in self.childs )
	{
		[child dump];
	}

	if ( self.target && self.target.dom.domName )
	{
		[[SamuraiLogger sharedInstance] unindent];

		PERF( @"</%@>", self.target.dom.domTag, self.target.dom.domName );
	}

#endif	// #if __SAMURAI_DEBUG__
}

@end

// ----------------------------------
// Unit test
// ----------------------------------

#pragma mark -

#if __SAMURAI_TESTING__

TEST_CASE( UI, RenderStoreNode )

DESCRIBE( before )
{
}

DESCRIBE( after )
{
}

TEST_CASE_END

#endif	// #if __SAMURAI_TESTING__

#endif	// #if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)

#import "_pragma_pop.h"


text:
using System;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

namespace Umbraco.Core.Dynamics
{
    /// <summary>
    /// Used to return the raw xml string value from DynamicXml when using type converters
    /// </summary>
    public class RawXmlString
    {
        public string Value { get; private set; }

        public RawXmlString(string value)
        {
            Value = value;
        }
    }

    /// <summary>
    /// Used to return the raw xml XElement value from DynamicXml when using type converters
    /// </summary>
    public class RawXElement
    {
        public XElement Value { get; private set; }

        public RawXElement(XElement value)
        {
            Value = value;
        }
    }

    /// <summary>
    /// Used to return the raw xml XElement value from DynamicXml when using type converters
    /// </summary>
    public class RawXmlElement
    {
        public XmlElement Value { get; private set; }

        public RawXmlElement(XmlElement value)
        {
            Value = value;
        }
    }

    /// <summary>
    /// Used to return the raw xml XmlDocument value from DynamicXml when using type converters
    /// </summary>
    public class RawXmlDocument
    {
        public XmlDocument Value { get; private set; }

        public RawXmlDocument(XmlDocument value)
        {
            Value = value;
        }
    }

	/// <summary>
	/// A custom type converter for DynamicXml
	/// </summary>
	public class DynamicXmlConverter : TypeConverter
	{
		public override bool CanConvertTo(ITypeDescriptorContext context, Type sourceType)
		{
			var convertableTypes = new[]
			    {
			        typeof(string),
                    typeof(XElement),
                    typeof(XmlElement),
                    typeof(XmlDocument),
                    typeof(RawXmlString),
                    typeof(RawXElement),
                    typeof(RawXmlElement),
                    typeof(RawXmlDocument)
			    };

			return convertableTypes.Any(x => TypeHelper.IsTypeAssignableFrom(x, sourceType))
			       || base.CanConvertFrom(context, sourceType);
		}

		public override object ConvertTo(
			ITypeDescriptorContext context,
			CultureInfo culture,
			object value,
			Type destinationType)
		{
			var dxml = value as DynamicXml;
			if (dxml == null)
				return null;
			//string
			if (TypeHelper.IsTypeAssignableFrom<string>(destinationType))
			{
				return value.ToString();
			}

			//XElement
			if (TypeHelper.IsTypeAssignableFrom<XElement>(destinationType))
			{
				return dxml.BaseElement;
			}
			//XmlElement
			if (TypeHelper.IsTypeAssignableFrom<XmlElement>(destinationType))
			{
				var xDoc = new XmlDocument();
				xDoc.LoadXml(dxml.ToString());
				return xDoc.DocumentElement;
			}
			//XmlDocument
			if (TypeHelper.IsTypeAssignableFrom<XmlDocument>(destinationType))
			{
				var xDoc = new XmlDocument();
				xDoc.LoadXml(dxml.ToString());
				return xDoc;
			}

            //RAW values:
            //string
            if (TypeHelper.IsTypeAssignableFrom<RawXmlString>(destinationType))
            {
                return new RawXmlString(dxml.ToRawXml());
            }
            //XElement
            if (TypeHelper.IsTypeAssignableFrom<RawXElement>(destinationType))
            {
                return new RawXElement(dxml.RawXmlElement);
            }
            //XmlElement
            if (TypeHelper.IsTypeAssignableFrom<RawXmlElement>(destinationType))
            {
                var xDoc = new XmlDocument();
                xDoc.LoadXml(dxml.ToRawXml());
                return new RawXmlElement(xDoc.DocumentElement);
            }
            //XmlDocument
            if (TypeHelper.IsTypeAssignableFrom<RawXmlDocument>(destinationType))
            {
                var xDoc = new XmlDocument();
                xDoc.LoadXml(dxml.ToRawXml());
                return new RawXmlDocument(xDoc);
            }

			return base.ConvertTo(context, culture, value, destinationType);
		}
	}
}


text:
import Ember from 'ember';
import Errors from 'ember-validations/errors';
import Base from 'ember-validations/validators/base';

var get = Ember.get;
var set = Ember.set;

var setValidityMixin = Ember.Mixin.create({
  isValid: Ember.computed('validators.@each.isValid', function() {
    var compactValidators = get(this, 'validators').compact();
    var filteredValidators = compactValidators.filter(function(validator) {
      return !get(validator, 'isValid');
    });

    return get(filteredValidators, 'length') === 0;
  }),
  isInvalid: Ember.computed.not('isValid')
});

var pushValidatableObject = function(model, property) {
  var content = get(model, property);

  model.removeObserver(property, pushValidatableObject);
  if (Ember.isArray(content)) {
    model.validators.pushObject(ArrayValidatorProxy.create({model: model, property: property, contentBinding: 'model.' + property}));
  } else {
    model.validators.pushObject(content);
  }
};

var lookupValidator = function(validatorName) {
  var container = get(this, 'container');
  var service = container.lookup('service:validations');
  var validators = [];
  var cache;

  if (service) {
    cache = get(service, 'cache');
  } else {
    cache = {};
  }

  if (cache[validatorName]) {
    validators = validators.concat(cache[validatorName]);
  } else {
    var local = container.lookupFactory('validator:local/'+validatorName);
    var remote = container.lookupFactory('validator:remote/'+validatorName);

    if (local || remote) { validators = validators.concat([local, remote]); }
    else {
      var base = container.lookupFactory('validator:'+validatorName);

      if (base) { validators = validators.concat([base]); }
      else {
        local = container.lookupFactory('ember-validations@validator:local/'+validatorName);
        remote = container.lookupFactory('ember-validations@validator:remote/'+validatorName);

        if (local || remote) { validators = validators.concat([local, remote]); }
      }
    }

    cache[validatorName] = validators;
  }

  if (Ember.isEmpty(validators)) {
    Ember.warn('Could not find the "'+validatorName+'" validator.');
  }

  return validators;
};

var ArrayValidatorProxy = Ember.ArrayProxy.extend(setValidityMixin, {
  validate: function() {
    return this._validate();
  },
  _validate: Ember.on('init', function() {
    var promises = get(this, 'content').invoke('_validate').without(undefined);
    return Ember.RSVP.all(promises);
  }),
  validators: Ember.computed.alias('content')
});

export default Ember.Mixin.create(setValidityMixin, {
  init: function() {
    this._super();
    this.errors = Errors.create();
    this.dependentValidationKeys = {};
    this.validators = Ember.A();
    if (get(this, 'validations') === undefined) {
      this.validations = {};
    }
    this.buildValidators();
    this.validators.forEach(function(validator) {
      validator.addObserver('errors.[]', this, function(sender) {
        var errors = Ember.A();
        this.validators.forEach(function(validator) {
          if (validator.property === sender.property) {
            errors.addObjects(validator.errors);
          }
        }, this);
        set(this, 'errors.' + sender.property, errors);
      });
    }, this);
  },
  buildValidators: function() {
    var property;

    for (property in this.validations) {
      if (this.validations[property].constructor === Object) {
        this.buildRuleValidator(property);
      } else {
        this.buildObjectValidator(property);
      }
    }
  },
  buildRuleValidator: function(property) {
    var pushValidator = function(validator) {
      if (validator) {
        this.validators.pushObject(validator.create({model: this, property: property, options: this.validations[property][validatorName]}));
      }
    };

    if (this.validations[property].callback) {
      this.validations[property] = { inline: this.validations[property] };
    }

    var createInlineClass = function(callback) {
      return Base.extend({
        call: function() {
          var errorMessage = this.callback.call(this);

          if (errorMessage) {
            this.errors.pushObject(errorMessage);
          }
        },
        callback: callback
      });
    };

    for (var validatorName in this.validations[property]) {
      if (validatorName === 'inline') {
        pushValidator.call(this, createInlineClass(this.validations[property][validatorName].callback));
      } else if (this.validations[property].hasOwnProperty(validatorName)) {
        lookupValidator.call(this, validatorName).forEach(pushValidator, this);
      }
    }
  },
  buildObjectValidator: function(property) {
    if (Ember.isNone(get(this, property))) {
      this.addObserver(property, this, pushValidatableObject);
    } else {
      pushValidatableObject(this, property);
    }
  },
  validate: function() {
    var self = this;
    return this._validate().then(function(vals) {
      var errors = get(self, 'errors');
      if (vals.indexOf(false) > -1) {
        return Ember.RSVP.reject(errors);
      }
      return errors;
    });
  },
  _validate: Ember.on('init', function() {
    var promises = this.validators.invoke('_validate').without(undefined);
    return Ember.RSVP.all(promises);
  })
});


text:
module Prometheus
  class CreateDefaultAlertsWorker
    include ApplicationWorker

    feature_category :incident_management
    urgency :high
    idempotent!

    def perform(project_id)
      project = Project.find_by_id(project_id)

      return unless project

      result = Prometheus::CreateDefaultAlertsService.new(project: project).execute

      log_info(result.message) if result.error?
    end

    private

    def log_info(message)
      logger.info(structured_payload(message: message))
    end
  end
end


text:
@interface ViewController ()

@end

@implementation ViewController
@synthesize theTableView,theaterList,theaterName,theaterAddress,theaterImage,movieTitle,movieRating,movieTimes,movieThumbnail,header,footer,footerProjectLabel,theaterNameLabel,theaterAddressLabel,theaterHeaderImage;

- (void)viewDidLoad
{
    appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    allMovies = appDelegate.movieList;
    theaterList = [allMovies.theaters objectForKey:@"TheatersList"];
    NSLog(@"%@", theaterList);
	[super viewDidLoad];
}

- (void)viewDidUnload
{
    [self setTheTableView:nil];
    [super viewDidUnload];

}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [theaterList count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    NSArray *movieList = [NSArray arrayWithArray:[[theaterList objectForKey:[NSString stringWithFormat:@"Theater %d", section]]objectForKey:@"Movies"]];
    NSLog(@"%@", movieList);
    NSInteger numMovies = [movieList count];
    return numMovies;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 55.0f;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 45.0f;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 220.0f;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
	footer = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, theTableView.frame.size.width, 50.0f)];
	[footer setBackgroundColor:[UIColor blackColor]];

	footerProjectLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 280.0f, 40.0f)];
    [footerProjectLabel setBackgroundColor:[UIColor clearColor]];
    [footerProjectLabel setFont:[UIFont systemFontOfSize:12.0f]];
    [footerProjectLabel setTextColor:[UIColor grayColor]];
	[footerProjectLabel setTextAlignment:NSTextAlignmentRight];
	[footerProjectLabel setText:@"MDF2 Project 4 :: Full Sail :: Monica Peters"];

	[footer addSubview:footerProjectLabel];
	return footer;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    header = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, theTableView.frame.size.width, 50.0f)];
    [header setBackgroundColor:[UIColor blackColor]];

	theaterNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(60.0f, 0.0f, 280.0f, 20.0f)];
    [theaterNameLabel setBackgroundColor:[UIColor clearColor]];
    [theaterNameLabel setFont:[UIFont boldSystemFontOfSize:18.0f]];
    [theaterNameLabel setTextColor:[UIColor whiteColor]];

	theaterAddressLabel = [[UILabel alloc] initWithFrame:CGRectMake(60.0f, 30.0f, 200.0f, 20.0f)];
    [theaterAddressLabel setBackgroundColor:[UIColor clearColor]];
    [theaterAddressLabel setFont:[UIFont boldSystemFontOfSize:14.0f]];
    [theaterAddressLabel setTextColor:[UIColor lightTextColor]];

	theaterHeaderImage = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 50.0f, 50.0f)];

    theaterName = [[[theaterList objectForKey:[NSString stringWithFormat:@"Theater %d",section]] objectForKey:@"TheaterInfo"]objectForKey:@"theaterName"];
    theaterImage = [[[theaterList objectForKey:[NSString stringWithFormat:@"Theater %d",section]] objectForKey:@"TheaterInfo"]objectForKey:@"theaterThumbnail"];
    theaterAddress = [[[theaterList objectForKey:[NSString stringWithFormat:@"Theater %d",section]] objectForKey:@"TheaterInfo"]objectForKey:@"address"];

    NSLog(@"theaterName %@ theaterAddress%@",theaterName, theaterAddress);

    if (theaterName != nil)
    {
        [theaterNameLabel setText:theaterName];
    }

    if (theaterAddress != nil)
    {
        [theaterAddressLabel setText:theaterAddress];
    }

    if (theaterImage != nil)
    {
        [theaterHeaderImage setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:theaterImage ofType:@"png" inDirectory:@"images"]]];
    }
	else
	{
		[theaterHeaderImage setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:theaterImage ofType:@"png" inDirectory:@"images"]]];
	}

    [header addSubview:theaterNameLabel];
    [header addSubview:theaterAddressLabel];
    [header addSubview:theaterHeaderImage];
	NSLog(@"%@", theaterHeaderImage);
    return header;
}

- (MovieTableCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"cell";
    MovieTableCell *movieCell = [tableView dequeueReusableCellWithIdentifier:cellID];

    NSArray *movieList = [NSArray arrayWithArray:[[theaterList objectForKey:[NSString stringWithFormat:@"Theater %d", indexPath.section]]objectForKey:@"Movies"]];

	movieTitle = [[movieList objectAtIndex:indexPath.row]objectForKey:@"title"];
    movieTimes = [[movieList objectAtIndex:indexPath.row]objectForKey:@"showtimes"];
    movieRating = [[movieList objectAtIndex:indexPath.row]objectForKey:@"rating"];
    movieThumbnail = [[movieList objectAtIndex:indexPath.row]objectForKey:@"thumbnail"];

    [movieCell.movieTitle setText:movieTitle];
    [movieCell.showTime setText:movieTimes];
    [movieCell.movieRating setText:movieRating];
    [movieCell.movieThumbnail setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:movieThumbnail ofType:@"png" inDirectory:@"images"]]];

    return movieCell;
}

#pragma Table View storyboard segue functions for selection, editing, deletion
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    UIViewController *destination = segue.destinationViewController;

    if([destination respondsToSelector:@selector(setDelegate:)])
    {
        [destination setValue:self forKey:@"delegate"];
    }
    if ([destination respondsToSelector:@selector(setSelectedItem:)])
    {
        NSIndexPath *indexPath = [self.theTableView indexPathForCell:sender];
        NSDictionary *item = [NSDictionary dictionaryWithDictionary:[[[theaterList objectForKey:[NSString stringWithFormat:@"Theater %d", indexPath.section]]objectForKey:@"Movies"]objectAtIndex:indexPath.row]];
        [destination setValue:item forKey:@"selectedItem"];
    }
}
@end


text:
namespace Osmosis {
namespace Client
{

Transfer::Transfer(       const std::string &            label,
		Chain::Chain &                 chain,
		Chain::ObjectStoreInterface &  destination ) :
	_label( label ),
	_chain( chain ),
	_destination( destination ),
	_toCheckExistingQueue( 1 ),
	_toTransferQueue( CHECK_EXISTING_THREADS )
{
	for ( unsigned i = 0; i < CHECK_EXISTING_THREADS; ++ i )
		_threads.push_back( std::thread(
			CheckExistingThread::task, std::ref( _toCheckExistingQueue ), std::ref( _toTransferQueue ), std::ref( destination ),
			std::ref( _checkExistingAlreadyProcessed ), std::ref( _checkExistingAlreadyProcessedLock ) ) );
	for ( unsigned i = 0; i < TRANSFER_THREADS; ++ i )
		_threads.push_back( std::thread(
			TransferThread::task, std::ref( _toTransferQueue ), std::ref( chain ), std::ref( destination ) ) );
}

Transfer::~Transfer()
{
	_toCheckExistingQueue.abort();
	_toTransferQueue.abort();
	for ( auto & i : _threads )
		if ( i.joinable() )
			i.join();
}

void Transfer::go()
{
	BACKTRACE_BEGIN
	auto connection = _destination.connect();
	checkLabelDoesNotExistInDestination( * connection );

	Chain::CheckOut checkOut( _chain.checkOut() );
	Hash labelHash = checkOut.getLabel( _label );
	DirList labelDirList = fetchDirList( labelHash, checkOut );

	populateToCheckExistingQueue( labelHash, labelDirList );
	for ( auto & i : _threads )
		i.join();
	connection->setLabel( labelHash, _label );
	BACKTRACE_END
}

void Transfer::checkLabelDoesNotExistInDestination( Chain::ObjectStoreConnectionInterface & connection )
{
	if ( connection.listLabels( "^" + _label + "$" ).size() > 0 )
		THROW( Error, "Label '" << _label << "' already exists at destination" );
}

void Transfer::populateToCheckExistingQueue( const Hash & labelHash, const DirList & labelDirList )
{
	BACKTRACE_BEGIN
	for ( auto & entry : labelDirList.entries() )
		if ( entry.hash )
			_toCheckExistingQueue.put( Digested( { entry.path, * entry.hash } ) );
	_toCheckExistingQueue.put( Digested( { boost::filesystem::path( "label" ), labelHash } ) );
	_toCheckExistingQueue.producerDone();
	BACKTRACE_END
}

DirList Transfer::fetchDirList( const Hash & labelHash, Chain::CheckOut & checkOut )
{
	BACKTRACE_BEGIN
	std::string dirListText = checkOut.getString( labelHash );
	if ( not CalculateHash::verify( dirListText.c_str(), dirListText.size(), labelHash ) )
		THROW( Error, "Dir list hash did not match contents" );
	std::istringstream dirListTextStream( std::move( dirListText ) );
	DirList labelDirList;
	dirListTextStream >> labelDirList;
	return std::move( labelDirList );
	BACKTRACE_END
}

} // namespace Client
} // namespace Osmosis


text:
#ifndef _WINCAP_H
#define _WINCAP_H

struct wincaps
{
  DWORD    def_guard_pages;
  DWORD    max_sys_priv;
  unsigned is_server                                    : 1;
  unsigned has_mandatory_integrity_control		: 1;
  unsigned needs_count_in_si_lpres2			: 1;
  unsigned has_recycle_dot_bin				: 1;
  unsigned has_gaa_on_link_prefix			: 1;
  unsigned has_gaa_largeaddress_bug			: 1;
  unsigned supports_all_posix_ai_flags			: 1;
  unsigned has_restricted_stack_args			: 1;
  unsigned has_transactions				: 1;
  unsigned has_sendmsg					: 1;
  unsigned has_broken_udf				: 1;
  unsigned has_broken_alloc_console			: 1;
  unsigned has_always_all_codepages			: 1;
  unsigned has_localenames				: 1;
  unsigned has_fast_cwd					: 1;
  unsigned has_restricted_raw_disk_access		: 1;
  unsigned use_dont_resolve_hack			: 1;
  unsigned has_console_logon_sid			: 1;
  unsigned wow64_has_secondary_stack			: 1;
  unsigned has_program_compatibility_assistant		: 1;
  unsigned has_pipe_reject_remote_clients		: 1;
  unsigned terminate_thread_frees_stack			: 1;
  unsigned has_precise_system_time			: 1;
  unsigned has_microsoft_accounts			: 1;
  unsigned has_set_thread_stack_guarantee		: 1;
  unsigned has_broken_rtl_query_process_debug_information : 1;
  unsigned has_processor_groups				: 1;
  unsigned has_broken_prefetchvm			: 1;
};

class wincapc
{
  SYSTEM_INFO		system_info;
  RTL_OSVERSIONINFOEXW	version;
  char			osnam[40];
  ULONG_PTR		wow64;
  void			*caps;

public:
  void init ();

  const DWORD cpu_count () const { return system_info.dwNumberOfProcessors; }
  /* The casts to size_t make sure that the returned value has the size of
     a pointer on any system.  This is important when using them for bit
     mask operations, like in roundup2. */
  const size_t page_size () const { return (size_t) system_info.dwPageSize; }
  const size_t allocation_granularity () const
		     { return (size_t) system_info.dwAllocationGranularity; }
  const char *osname () const { return osnam; }
  const bool is_wow64 () const { return !!wow64; }

#define IMPLEMENT(cap) cap() const { return ((wincaps *) this->caps)->cap; }

  DWORD def_guard_page_size () const
  {
    return ((wincaps *) this->caps)->def_guard_pages * page_size ();
  }
  DWORD IMPLEMENT (max_sys_priv)
  bool  IMPLEMENT (is_server)
  bool	IMPLEMENT (has_mandatory_integrity_control)
  bool	IMPLEMENT (needs_count_in_si_lpres2)
  bool	IMPLEMENT (has_recycle_dot_bin)
  bool	IMPLEMENT (has_gaa_on_link_prefix)
  bool	IMPLEMENT (has_gaa_largeaddress_bug)
  bool	IMPLEMENT (supports_all_posix_ai_flags)
  bool	IMPLEMENT (has_restricted_stack_args)
  bool	IMPLEMENT (has_transactions)
  bool	IMPLEMENT (has_sendmsg)
  bool	IMPLEMENT (has_broken_udf)
  bool	IMPLEMENT (has_broken_alloc_console)
  bool	IMPLEMENT (has_always_all_codepages)
  bool	IMPLEMENT (has_localenames)
  bool	IMPLEMENT (has_fast_cwd)
  bool	IMPLEMENT (has_restricted_raw_disk_access)
  bool	IMPLEMENT (use_dont_resolve_hack)
  bool	IMPLEMENT (has_console_logon_sid)
  bool	IMPLEMENT (wow64_has_secondary_stack)
  bool	IMPLEMENT (has_program_compatibility_assistant)
  bool	IMPLEMENT (has_pipe_reject_remote_clients)
  bool	IMPLEMENT (terminate_thread_frees_stack)
  bool	IMPLEMENT (has_precise_system_time)
  bool	IMPLEMENT (has_microsoft_accounts)
  bool	IMPLEMENT (has_set_thread_stack_guarantee)
  bool	IMPLEMENT (has_broken_rtl_query_process_debug_information)
  bool	IMPLEMENT (has_processor_groups)
  bool	IMPLEMENT (has_broken_prefetchvm)

#undef IMPLEMENT
};

extern wincapc wincap;

#endif /* _WINCAP_H */


text:
namespace views {
class MessageBoxView;
}

namespace javascript_dialogs {

class AppModalDialogController;

class AppModalDialogViewViews : public AppModalDialogView,
                                public views::DialogDelegate {
 public:
  explicit AppModalDialogViewViews(AppModalDialogController* controller);
  ~AppModalDialogViewViews() override;

  // AppModalDialogView:
  void ShowAppModalDialog() override;
  void ActivateAppModalDialog() override;
  void CloseAppModalDialog() override;
  void AcceptAppModalDialog() override;
  void CancelAppModalDialog() override;
  bool IsShowing() const override;

  // views::DialogDelegate:
  base::string16 GetWindowTitle() const override;
  void DeleteDelegate() override;
  ui::ModalType GetModalType() const override;
  views::View* GetContentsView() override;
  views::View* GetInitiallyFocusedView() override;
  views::Widget* GetWidget() override;
  const views::Widget* GetWidget() const override;
  bool ShouldShowCloseButton() const override;
  void WindowClosing() override;

 private:
  std::unique_ptr<AppModalDialogController> controller_;

  // The message box view whose commands we handle.
  views::MessageBoxView* message_box_view_;

  DISALLOW_COPY_AND_ASSIGN(AppModalDialogViewViews);
};

}  // namespace javascript_dialogs

#endif  // COMPONENTS_JAVASCRIPT_DIALOGS_VIEWS_APP_MODAL_DIALOG_VIEW_VIEWS_H_