virConnectGetDomainCapabilities(virConnectPtr conn,
                                const char *emulatorbin,
                                const char *arch,
                                const char *machine,
                                const char *virttype,
                                unsigned int flags)
{
    VIR_DEBUG("conn=%p, emulatorbin=%s, arch=%s, "
              "machine=%s, virttype=%s, flags=%x",
              conn, NULLSTR(emulatorbin), NULLSTR(arch),
              NULLSTR(machine), NULLSTR(virttype), flags);

    virResetLastError();

    virCheckConnectReturn(conn, NULL);

    if (conn->driver->connectGetDomainCapabilities) {
        char *ret;
        ret = conn->driver->connectGetDomainCapabilities(conn, emulatorbin,
                                                         arch, machine,
                                                         virttype, flags);
        if (!ret)
            goto error;
        VIR_DEBUG("conn=%p, ret=%s", conn, ret);
        return ret;
    }

    virReportUnsupportedError();

 error:
    virDispatchError(conn);
    return NULL;
}


virDomainDestroyFlags(virDomainPtr domain,
                      unsigned int flags)
{
    virConnectPtr conn;

    VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);

    virResetLastError();

    virCheckDomainReturn(domain, -1);
    conn = domain->conn;

    virCheckReadOnlyGoto(conn->flags, error);

    if (conn->driver->domainDestroyFlags) {
        int ret;
        ret = conn->driver->domainDestroyFlags(domain, flags);
        if (ret < 0)
            goto error;
        return ret;
    }

    virReportUnsupportedError();

 error:
    virDispatchError(conn);
    return -1;
}


virDomainMigratePrepare(virConnectPtr dconn,
                        char **cookie,
                        int *cookielen,
                        const char *uri_in,
                        char **uri_out,
                        unsigned long flags,
                        const char *dname,
                        unsigned long bandwidth)
{
    VIR_DEBUG("dconn=%p, cookie=%p, cookielen=%p, uri_in=%s, uri_out=%p, "
              "flags=%lx, dname=%s, bandwidth=%lu", dconn, cookie, cookielen,
              NULLSTR(uri_in), uri_out, flags, NULLSTR(dname), bandwidth);

    virResetLastError();

    virCheckConnectReturn(dconn, -1);
    virCheckReadOnlyGoto(dconn->flags, error);

    if (dconn->driver->domainMigratePrepare) {
        int ret;
        ret = dconn->driver->domainMigratePrepare(dconn, cookie, cookielen,
                                                  uri_in, uri_out,
                                                  flags, dname, bandwidth);
        if (ret < 0)
            goto error;
        return ret;
    }

    virReportUnsupportedError();

 error:
    virDispatchError(dconn);
    return -1;
}


virDomainIOThreadInfoFree(virDomainIOThreadInfoPtr info)
{
    if (!info)
        return;

    VIR_FREE(info->cpumap);
    VIR_FREE(info);
}


virDomainMigrateVersion2(virDomainPtr domain,
                         virConnectPtr dconn,
                         unsigned long flags,
                         const char *dname,
                         const char *uri,
                         unsigned long bandwidth)
{
    virDomainPtr ddomain = NULL;
    char *uri_out = NULL;
    char *cookie = NULL;
    char *dom_xml = NULL;
    int cookielen = 0, ret;
    virDomainInfo info;
    virErrorPtr orig_err = NULL;
    unsigned int getxml_flags = 0;
    int cancelled;
    unsigned long destflags;

    VIR_DOMAIN_DEBUG(domain,
                     "dconn=%p, flags=%lx, dname=%s, uri=%s, bandwidth=%lu",
                     dconn, flags, NULLSTR(dname), NULLSTR(uri), bandwidth);

    /* Prepare the migration.
     *
     * The destination host may return a cookie, or leave cookie as
     * NULL.
     *
     * The destination host MUST set uri_out if uri_in is NULL.
     *
     * If uri_in is non-NULL, then the destination host may modify
     * the URI by setting uri_out.  If it does not wish to modify
     * the URI, it should leave uri_out as NULL.
     */

    /* In version 2 of the protocol, the prepare step is slightly
     * different.  We fetch the domain XML of the source domain
     * and pass it to Prepare2.
     */
    if (!domain->conn->driver->domainGetXMLDesc) {
        virReportUnsupportedError();
        return NULL;
    }

    if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                 VIR_DRV_FEATURE_XML_MIGRATABLE)) {
        getxml_flags |= VIR_DOMAIN_XML_MIGRATABLE;
    } else {
        getxml_flags |= VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_UPDATE_CPU;
    }

    dom_xml = domain->conn->driver->domainGetXMLDesc(domain, getxml_flags);
    if (!dom_xml)
        return NULL;

    ret = virDomainGetInfo(domain, &info);
    if (ret == 0 && info.state == VIR_DOMAIN_PAUSED)
        flags |= VIR_MIGRATE_PAUSED;

    destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR |
                          VIR_MIGRATE_AUTO_CONVERGE);

    VIR_DEBUG("Prepare2 %p flags=%lx", dconn, destflags);
    ret = dconn->driver->domainMigratePrepare2
        (dconn, &cookie, &cookielen, uri, &uri_out, destflags, dname,
         bandwidth, dom_xml);
    VIR_FREE(dom_xml);
    if (ret == -1)
        goto done;

    if (uri == NULL && uri_out == NULL) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("domainMigratePrepare2 did not set uri"));
        cancelled = 1;
        /* Make sure Finish doesn't overwrite the error */
        orig_err = virSaveLastError();
        goto finish;
    }
    if (uri_out)
        uri = uri_out; /* Did domainMigratePrepare2 change URI? */

    /* Perform the migration.  The driver isn't supposed to return
     * until the migration is complete.
     */
    VIR_DEBUG("Perform %p", domain->conn);
    ret = domain->conn->driver->domainMigratePerform
        (domain, cookie, cookielen, uri, flags, dname, bandwidth);

    /* Perform failed. Make sure Finish doesn't overwrite the error */
    if (ret < 0)
        orig_err = virSaveLastError();

    /* If Perform returns < 0, then we need to cancel the VM
     * startup on the destination
     */
    cancelled = ret < 0 ? 1 : 0;

 finish:
    /* In version 2 of the migration protocol, we pass the
     * status code from the sender to the destination host,
     * so it can do any cleanup if the migration failed.
     */
    dname = dname ? dname : domain->name;
    VIR_DEBUG("Finish2 %p ret=%d", dconn, ret);
    ddomain = dconn->driver->domainMigrateFinish2
        (dconn, dname, cookie, cookielen, uri, destflags, cancelled);
    if (cancelled && ddomain)
        VIR_ERROR(_("finish step ignored that migration was cancelled"));

 done:
    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }
    VIR_FREE(uri_out);
    VIR_FREE(cookie);
    return ddomain;
}


static void power_mem_write(void *opaque, hwaddr addr,
                            uint64_t val, unsigned size)
{
    /* According to a real Ultra 5, bit 24 controls the power */
    if (val & 0x1000000) {
        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
    }
}


static void rdma_umap_priv_init(struct rdma_umap_priv *priv,
				struct vm_area_struct *vma)
{
	struct ib_uverbs_file *ufile = vma->vm_file->private_data;

	priv->vma = vma;
	vma->vm_private_data = priv;
	vma->vm_ops = &rdma_umap_ops;

	mutex_lock(&ufile->umap_lock);
	list_add(&priv->list, &ufile->umaps);
	mutex_unlock(&ufile->umap_lock);
}


static inline int is_mergeable_vma(struct vm_area_struct *vma,
				struct file *file, unsigned long vm_flags,
				struct vm_userfaultfd_ctx vm_userfaultfd_ctx)
{
	/*
	 * VM_SOFTDIRTY should not prevent from VMA merging, if we
	 * match the flags but dirty bit -- the caller should mark
	 * merged VMA as dirty. If dirty bit won't be excluded from
	 * comparison, we increase pressure on the memory system forcing
	 * the kernel to generate new VMAs when old one could be
	 * extended instead.
	 */
	if ((vma->vm_flags ^ vm_flags) & ~VM_SOFTDIRTY)
		return 0;
	if (vma->vm_file != file)
		return 0;
	if (vma->vm_ops && vma->vm_ops->close)
		return 0;
	if (!is_mergeable_vm_userfaultfd_ctx(vma, vm_userfaultfd_ctx))
		return 0;
	return 1;
}


static inline void __fs_reclaim_release(void) { }


void ib_uverbs_release_uevent(struct ib_uverbs_file *file,
			      struct ib_uevent_object *uobj)
{
	struct ib_uverbs_event *evt, *tmp;

	spin_lock_irq(&file->async_file->ev_queue.lock);
	list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
		list_del(&evt->list);
		kfree(evt);
	}
	spin_unlock_irq(&file->async_file->ev_queue.lock);
}


static void smaps_pte_entry(pte_t *pte, unsigned long addr,
		struct mm_walk *walk)
{
	struct mem_size_stats *mss = walk->private;
	struct vm_area_struct *vma = walk->vma;
	bool locked = !!(vma->vm_flags & VM_LOCKED);
	struct page *page = NULL;

	if (pte_present(*pte)) {
		page = vm_normal_page(vma, addr, *pte);
	} else if (is_swap_pte(*pte)) {
		swp_entry_t swpent = pte_to_swp_entry(*pte);

		if (!non_swap_entry(swpent)) {
			int mapcount;

			mss->swap += PAGE_SIZE;
			mapcount = swp_swapcount(swpent);
			if (mapcount >= 2) {
				u64 pss_delta = (u64)PAGE_SIZE << PSS_SHIFT;

				do_div(pss_delta, mapcount);
				mss->swap_pss += pss_delta;
			} else {
				mss->swap_pss += (u64)PAGE_SIZE << PSS_SHIFT;
			}
		} else if (is_migration_entry(swpent))
			page = migration_entry_to_page(swpent);
		else if (is_device_private_entry(swpent))
			page = device_private_entry_to_page(swpent);
	} else if (unlikely(IS_ENABLED(CONFIG_SHMEM) && mss->check_shmem_swap
							&& pte_none(*pte))) {
		page = find_get_entry(vma->vm_file->f_mapping,
						linear_page_index(vma, addr));
		if (!page)
			return;

		if (xa_is_value(page))
			mss->swap += PAGE_SIZE;
		else
			put_page(page);

		return;
	}

	if (!page)
		return;

	smaps_account(mss, page, false, pte_young(*pte), pte_dirty(*pte), locked);
}


static inline void memalloc_noreclaim_restore(unsigned int flags)
{
	current->flags = (current->flags & ~PF_MEMALLOC) | flags;
}


static inline unsigned int memalloc_noreclaim_save(void)
{
	unsigned int flags = current->flags & PF_MEMALLOC;
	current->flags |= PF_MEMALLOC;
	return flags;
}


static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
				unsigned long end, struct mm_walk *walk)
{
	struct clear_refs_private *cp = walk->private;
	struct vm_area_struct *vma = walk->vma;
	pte_t *pte, ptent;
	spinlock_t *ptl;
	struct page *page;

	ptl = pmd_trans_huge_lock(pmd, vma);
	if (ptl) {
		if (cp->type == CLEAR_REFS_SOFT_DIRTY) {
			clear_soft_dirty_pmd(vma, addr, pmd);
			goto out;
		}

		if (!pmd_present(*pmd))
			goto out;

		page = pmd_page(*pmd);

		/* Clear accessed and referenced bits. */
		pmdp_test_and_clear_young(vma, addr, pmd);
		test_and_clear_page_young(page);
		ClearPageReferenced(page);
out:
		spin_unlock(ptl);
		return 0;
	}

	if (pmd_trans_unstable(pmd))
		return 0;

	pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
	for (; addr != end; pte++, addr += PAGE_SIZE) {
		ptent = *pte;

		if (cp->type == CLEAR_REFS_SOFT_DIRTY) {
			clear_soft_dirty(vma, addr, pte);
			continue;
		}

		if (!pte_present(ptent))
			continue;

		page = vm_normal_page(vma, addr, ptent);
		if (!page)
			continue;

		/* Clear accessed and referenced bits. */
		ptep_test_and_clear_young(vma, addr, pte);
		test_and_clear_page_young(page);
		ClearPageReferenced(page);
	}
	pte_unmap_unlock(pte - 1, ptl);
	cond_resched();
	return 0;
}


void ib_uverbs_init_event_queue(struct ib_uverbs_event_queue *ev_queue)
{
	spin_lock_init(&ev_queue->lock);
	INIT_LIST_HEAD(&ev_queue->event_list);
	init_waitqueue_head(&ev_queue->poll_wait);
	ev_queue->is_closed   = 0;
	ev_queue->async_queue = NULL;
}


static inline void clear_soft_dirty_pmd(struct vm_area_struct *vma,
		unsigned long addr, pmd_t *pmdp)
{
	pmd_t old, pmd = *pmdp;

	if (pmd_present(pmd)) {
		/* See comment in change_huge_pmd() */
		old = pmdp_invalidate(vma, addr, pmdp);
		if (pmd_dirty(old))
			pmd = pmd_mkdirty(pmd);
		if (pmd_young(old))
			pmd = pmd_mkyoung(pmd);

		pmd = pmd_wrprotect(pmd);
		pmd = pmd_clear_soft_dirty(pmd);

		set_pmd_at(vma->vm_mm, addr, pmdp, pmd);
	} else if (is_migration_entry(pmd_to_swp_entry(pmd))) {
		pmd = pmd_swp_clear_soft_dirty(pmd);
		set_pmd_at(vma->vm_mm, addr, pmdp, pmd);
	}
}


static void ib_uverbs_free_hw_resources(struct ib_uverbs_device *uverbs_dev,
					struct ib_device *ib_dev)
{
	struct ib_uverbs_file *file;
	struct ib_uverbs_async_event_file *event_file;
	struct ib_event event;

	/* Pending running commands to terminate */
	uverbs_disassociate_api_pre(uverbs_dev);
	event.event = IB_EVENT_DEVICE_FATAL;
	event.element.port_num = 0;
	event.device = ib_dev;

	mutex_lock(&uverbs_dev->lists_mutex);
	while (!list_empty(&uverbs_dev->uverbs_file_list)) {
		file = list_first_entry(&uverbs_dev->uverbs_file_list,
					struct ib_uverbs_file, list);
		list_del_init(&file->list);
		kref_get(&file->ref);

		/* We must release the mutex before going ahead and calling
		 * uverbs_cleanup_ufile, as it might end up indirectly calling
		 * uverbs_close, for example due to freeing the resources (e.g
		 * mmput).
		 */
		mutex_unlock(&uverbs_dev->lists_mutex);

		ib_uverbs_event_handler(&file->event_handler, &event);
		uverbs_destroy_ufile_hw(file, RDMA_REMOVE_DRIVER_REMOVE);
		kref_put(&file->ref, ib_uverbs_release_file);

		mutex_lock(&uverbs_dev->lists_mutex);
	}

	while (!list_empty(&uverbs_dev->uverbs_events_file_list)) {
		event_file = list_first_entry(&uverbs_dev->
					      uverbs_events_file_list,
					      struct ib_uverbs_async_event_file,
					      list);
		spin_lock_irq(&event_file->ev_queue.lock);
		event_file->ev_queue.is_closed = 1;
		spin_unlock_irq(&event_file->ev_queue.lock);

		list_del(&event_file->list);
		ib_unregister_event_handler(
			&event_file->uverbs_file->event_handler);
		event_file->uverbs_file->event_handler.device =
			NULL;

		wake_up_interruptible(&event_file->ev_queue.poll_wait);
		kill_fasync(&event_file->ev_queue.async_queue, SIGIO, POLL_IN);
	}
	mutex_unlock(&uverbs_dev->lists_mutex);

	uverbs_disassociate_api(uverbs_dev->uapi);
}


static void userfaultfd_ctx_put(struct userfaultfd_ctx *ctx)
{
	if (refcount_dec_and_test(&ctx->refcount)) {
		VM_BUG_ON(spin_is_locked(&ctx->fault_pending_wqh.lock));
		VM_BUG_ON(waitqueue_active(&ctx->fault_pending_wqh));
		VM_BUG_ON(spin_is_locked(&ctx->fault_wqh.lock));
		VM_BUG_ON(waitqueue_active(&ctx->fault_wqh));
		VM_BUG_ON(spin_is_locked(&ctx->event_wqh.lock));
		VM_BUG_ON(waitqueue_active(&ctx->event_wqh));
		VM_BUG_ON(spin_is_locked(&ctx->fd_wqh.lock));
		VM_BUG_ON(waitqueue_active(&ctx->fd_wqh));
		mmdrop(ctx->mm);
		kmem_cache_free(userfaultfd_ctx_cachep, ctx);
	}
}


  bool List::operator== (const Expression& rhs) const
  {
    if (List_Ptr_Const r = Cast<List>(&rhs)) {
      if (length() != r->length()) return false;
      if (separator() != r->separator()) return false;
      for (size_t i = 0, L = length(); i < L; ++i) {
        Expression_Obj rv = r->at(i);
        Expression_Obj lv = this->at(i);
        if (!lv || !rv) return false;
        if (!(*lv == *rv)) return false;
      }
      return true;
    }
    return false;
  }


std::string rtrim(const std::string &str) {
  std::string trimmed = str;
  size_t pos_ws = trimmed.find_last_not_of(" \t\n\v\f\r");
  if (pos_ws != std::string::npos) {
    trimmed.erase(pos_ws + 1);
  } else {
    trimmed.clear();
  }
  return trimmed;
}


  Declaration_Obj Parser::parse_declaration() {
    String_Obj prop;
    bool is_custom_property = false;
    if (lex< sequence< optional< exactly<'*'> >, identifier_schema > >()) {
      const std::string property(lexed);
      is_custom_property = property.compare(0, 2, "--") == 0;
      prop = parse_identifier_schema();
    }
    else if (lex< sequence< optional< exactly<'*'> >, identifier, zero_plus< block_comment > > >()) {
      const std::string property(lexed);
      is_custom_property = property.compare(0, 2, "--") == 0;
      prop = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
    }
    else {
      css_error("Invalid CSS", " after ", ": expected \"}\", was ");
    }
    bool is_indented = true;
    const std::string property(lexed);
    if (!lex_css< one_plus< exactly<':'> > >()) error("property \"" + escape_string(property)  + "\" must be followed by a ':'");
    if (!is_custom_property && match< sequence< optional_css_comments, exactly<';'> > >()) error("style declaration must contain a value");
    if (match< sequence< optional_css_comments, exactly<'{'> > >()) is_indented = false; // don't indent if value is empty
    if (is_custom_property) {
      return SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, parse_css_variable_value(), false, true);
    }
    lex < css_comments >(false);
    if (peek_css< static_value >()) {
      return SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, parse_static_value()/*, lex<kwd_important>()*/);
    }
    else {
      Expression_Obj value;
      Lookahead lookahead = lookahead_for_value(position);
      if (lookahead.found) {
        if (lookahead.has_interpolants) {
          value = parse_value_schema(lookahead.found);
        } else {
          value = parse_list(DELAYED);
        }
      }
      else {
        value = parse_list(DELAYED);
        if (List* list = Cast<List>(value)) {
          if (!list->is_bracketed() && list->length() == 0 && !peek< exactly <'{'> >()) {
            css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
          }
        }
      }
      lex < css_comments >(false);
      Declaration_Obj decl = SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, value/*, lex<kwd_important>()*/);
      decl->is_indented(is_indented);
      decl->update_pstate(pstate);
      return decl;
    }
  }


struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
				  netdev_features_t features)
{
	struct sock *sk = gso_skb->sk;
	unsigned int sum_truesize = 0;
	struct sk_buff *segs, *seg;
	struct udphdr *uh;
	unsigned int mss;
	bool copy_dtor;
	__sum16 check;
	__be16 newlen;

	mss = skb_shinfo(gso_skb)->gso_size;
	if (gso_skb->len <= sizeof(*uh) + mss)
		return ERR_PTR(-EINVAL);

	skb_pull(gso_skb, sizeof(*uh));

	/* clear destructor to avoid skb_segment assigning it to tail */
	copy_dtor = gso_skb->destructor == sock_wfree;
	if (copy_dtor)
		gso_skb->destructor = NULL;

	segs = skb_segment(gso_skb, features);
	if (unlikely(IS_ERR_OR_NULL(segs))) {
		if (copy_dtor)
			gso_skb->destructor = sock_wfree;
		return segs;
	}

	/* GSO partial and frag_list segmentation only requires splitting
	 * the frame into an MSS multiple and possibly a remainder, both
	 * cases return a GSO skb. So update the mss now.
	 */
	if (skb_is_gso(segs))
		mss *= skb_shinfo(segs)->gso_segs;

	seg = segs;
	uh = udp_hdr(seg);

	/* compute checksum adjustment based on old length versus new */
	newlen = htons(sizeof(*uh) + mss);
	check = csum16_add(csum16_sub(uh->check, uh->len), newlen);

	for (;;) {
		if (copy_dtor) {
			seg->destructor = sock_wfree;
			seg->sk = sk;
			sum_truesize += seg->truesize;
		}

		if (!seg->next)
			break;

		uh->len = newlen;
		uh->check = check;

		if (seg->ip_summed == CHECKSUM_PARTIAL)
			gso_reset_checksum(seg, ~check);
		else
			uh->check = gso_make_checksum(seg, ~check) ? :
				    CSUM_MANGLED_0;

		seg = seg->next;
		uh = udp_hdr(seg);
	}

	/* last packet can be partial gso_size, account for that in checksum */
	newlen = htons(skb_tail_pointer(seg) - skb_transport_header(seg) +
		       seg->data_len);
	check = csum16_add(csum16_sub(uh->check, uh->len), newlen);

	uh->len = newlen;
	uh->check = check;

	if (seg->ip_summed == CHECKSUM_PARTIAL)
		gso_reset_checksum(seg, ~check);
	else
		uh->check = gso_make_checksum(seg, ~check) ? : CSUM_MANGLED_0;

	/* update refcount for the packet */
	if (copy_dtor) {
		int delta = sum_truesize - gso_skb->truesize;

		/* In some pathological cases, delta can be negative.
		 * We need to either use refcount_add() or refcount_sub_and_test()
		 */
		if (likely(delta >= 0))
			refcount_add(delta, &sk->sk_wmem_alloc);
		else
			WARN_ON_ONCE(refcount_sub_and_test(-delta, &sk->sk_wmem_alloc));
	}
	return segs;
}


ModuleExport void UnregisterXWDImage(void)
{
  (void) UnregisterMagickInfo("XWD");
}


static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
#define CheckOverflowException(length,width,height) \
  (((height) != 0) && ((length)/((size_t) height) != ((size_t) width)))

  char
    *comment;

  Image
    *image;

  IndexPacket
    index;

  int
    x_status;

  MagickBooleanType
    authentic_colormap;

  MagickStatusType
    status;

  register IndexPacket
    *indexes;

  register ssize_t
    x;

  register PixelPacket
    *q;

  register ssize_t
    i;

  register size_t
    pixel;

  size_t
    length;

  ssize_t
    count,
    y;

  unsigned long
    lsb_first;

  XColor
    *colors;

  XImage
    *ximage;

  XWDFileHeader
    header;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickCoreSignature);
  image=AcquireImage(image_info);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  /*
     Read in header information.
  */
  count=ReadBlob(image,sz_XWDheader,(unsigned char *) &header);
  if (count != sz_XWDheader)
    ThrowReaderException(CorruptImageError,"UnableToReadImageHeader");
  /*
    Ensure the header byte-order is most-significant byte first.
  */
  lsb_first=1;
  if ((int) (*(char *) &lsb_first) != 0)
    MSBOrderLong((unsigned char *) &header,sz_XWDheader);
  /*
    Check to see if the dump file is in the proper format.
  */
  if (header.file_version != XWD_FILE_VERSION)
    ThrowReaderException(CorruptImageError,"FileFormatVersionMismatch");
  if (header.header_size < sz_XWDheader)
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  if ((header.bits_per_pixel == 0) || (header.bits_per_pixel > 32))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  if ((header.bitmap_bit_order != MSBFirst) &&
      (header.bitmap_bit_order != LSBFirst))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  if (((header.bitmap_pad % 8) != 0) || (header.bitmap_pad > 32))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  if (header.bitmap_unit > 32)
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  if (header.ncolors > 256)
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  switch (header.visual_class)
  {
    case StaticGray:
    case GrayScale:
    case StaticColor:
    case PseudoColor:
    case TrueColor:
    case DirectColor:
      break;
    default:
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  }
  switch (header.pixmap_format)
  {
    case XYBitmap:
    case XYPixmap:
    case ZPixmap:
      break;
    default:
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  }
  length=(size_t) (header.header_size-sz_XWDheader);
  if ((length+1) != ((size_t) ((CARD32) (length+1))))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  comment=(char *) AcquireQuantumMemory(length+1,sizeof(*comment));
  if (comment == (char *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  count=ReadBlob(image,length,(unsigned char *) comment);
  comment[length]='\0';
  (void) SetImageProperty(image,"comment",comment);
  comment=DestroyString(comment);
  if (count != (ssize_t) length)
    ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
  /*
    Initialize the X image.
  */
  ximage=(XImage *) AcquireMagickMemory(sizeof(*ximage));
  if (ximage == (XImage *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  ximage->depth=(int) header.pixmap_depth;
  ximage->format=(int) header.pixmap_format;
  ximage->xoffset=(int) header.xoffset;
  ximage->data=(char *) NULL;
  ximage->width=(int) header.pixmap_width;
  ximage->height=(int) header.pixmap_height;
  ximage->bitmap_pad=(int) header.bitmap_pad;
  ximage->bytes_per_line=(int) header.bytes_per_line;
  ximage->byte_order=(int) header.byte_order;
  ximage->bitmap_unit=(int) header.bitmap_unit;
  ximage->bitmap_bit_order=(int) header.bitmap_bit_order;
  ximage->bits_per_pixel=(int) header.bits_per_pixel;
  ximage->red_mask=header.red_mask;
  ximage->green_mask=header.green_mask;
  ximage->blue_mask=header.blue_mask;
  if ((ximage->width < 0) || (ximage->height < 0) || (ximage->depth < 0) ||
      (ximage->format < 0) || (ximage->byte_order < 0) ||
      (ximage->bitmap_bit_order < 0) || (ximage->bitmap_pad < 0) ||
      (ximage->bytes_per_line < 0))
    {
      ximage=(XImage *) RelinquishMagickMemory(ximage);
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    }
  if ((ximage->width > 65535) || (ximage->height > 65535))
    {
      ximage=(XImage *) RelinquishMagickMemory(ximage);
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    }
  if ((ximage->bits_per_pixel > 32) || (ximage->bitmap_unit > 32))
    {
      ximage=(XImage *) RelinquishMagickMemory(ximage);
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    }
  x_status=XInitImage(ximage);
  if (x_status == 0)
    {
      ximage=(XImage *) RelinquishMagickMemory(ximage);
      ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
    }
  /*
    Read colormap.
  */
  authentic_colormap=MagickFalse;
  colors=(XColor *) NULL;
  if (header.ncolors != 0)
    {
      XWDColor
        color;

      length=(size_t) header.ncolors;
      if (length > ((~0UL)/sizeof(*colors)))
        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
      colors=(XColor *) AcquireQuantumMemory(length,sizeof(*colors));
      if (colors == (XColor *) NULL)
        {
          ximage=(XImage *) RelinquishMagickMemory(ximage);
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        }
      for (i=0; i < (ssize_t) header.ncolors; i++)
      {
        count=ReadBlob(image,sz_XWDColor,(unsigned char *) &color);
        if (count != sz_XWDColor)
          {
            colors=(XColor *) RelinquishMagickMemory(colors);
            ximage=(XImage *) RelinquishMagickMemory(ximage);
            ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
          }
        colors[i].pixel=color.pixel;
        colors[i].red=color.red;
        colors[i].green=color.green;
        colors[i].blue=color.blue;
        colors[i].flags=(char) color.flags;
        if (color.flags != 0)
          authentic_colormap=MagickTrue;
      }
      /*
        Ensure the header byte-order is most-significant byte first.
      */
      lsb_first=1;
      if ((int) (*(char *) &lsb_first) != 0)
        for (i=0; i < (ssize_t) header.ncolors; i++)
        {
          MSBOrderLong((unsigned char *) &colors[i].pixel,
            sizeof(colors[i].pixel));
          MSBOrderShort((unsigned char *) &colors[i].red,3*
            sizeof(colors[i].red));
        }
    }
  /*
    Allocate the pixel buffer.
  */
  length=(size_t) ximage->bytes_per_line*ximage->height;
  if (CheckOverflowException(length,ximage->bytes_per_line,ximage->height))
    {
      if (header.ncolors != 0)
        colors=(XColor *) RelinquishMagickMemory(colors);
      ximage=(XImage *) RelinquishMagickMemory(ximage);
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    }
  if (ximage->format != ZPixmap)
    {
      size_t
        extent;

      extent=length;
      length*=ximage->depth;
      if (CheckOverflowException(length,extent,ximage->depth))
        {
          if (header.ncolors != 0)
            colors=(XColor *) RelinquishMagickMemory(colors);
          ximage=(XImage *) RelinquishMagickMemory(ximage);
          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
        }
    }
  ximage->data=(char *) AcquireQuantumMemory(length,sizeof(*ximage->data));
  if (ximage->data == (char *) NULL)
    {
      if (header.ncolors != 0)
        colors=(XColor *) RelinquishMagickMemory(colors);
      ximage=(XImage *) RelinquishMagickMemory(ximage);
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
     }
  count=ReadBlob(image,length,(unsigned char *) ximage->data);
  if (count != (ssize_t) length)
    {
      if (header.ncolors != 0)
        colors=(XColor *) RelinquishMagickMemory(colors);
      ximage->data=DestroyString(ximage->data);
      ximage=(XImage *) RelinquishMagickMemory(ximage);
      ThrowReaderException(CorruptImageError,"UnableToReadImageData");
    }
  /*
    Convert image to MIFF format.
  */
  image->columns=(size_t) ximage->width;
  image->rows=(size_t) ximage->height;
  image->depth=8;
  status=SetImageExtent(image,image->columns,image->rows);
  if (status == MagickFalse)
    {
      if (header.ncolors != 0)
        colors=(XColor *) RelinquishMagickMemory(colors);
      ximage->data=DestroyString(ximage->data);
      ximage=(XImage *) RelinquishMagickMemory(ximage);
      InheritException(exception,&image->exception);
      return(DestroyImageList(image));
    }
  if ((header.ncolors == 0U) || (ximage->red_mask != 0) ||
      (ximage->green_mask != 0) || (ximage->blue_mask != 0))
    image->storage_class=DirectClass;
  else
    image->storage_class=PseudoClass;
  image->colors=header.ncolors;
  if (image_info->ping == MagickFalse)
    switch (image->storage_class)
    {
      case DirectClass:
      default:
      {
        register size_t
          color;

        size_t
          blue_mask,
          blue_shift,
          green_mask,
          green_shift,
          red_mask,
          red_shift;

        /*
          Determine shift and mask for red, green, and blue.
        */
        red_mask=ximage->red_mask;
        red_shift=0;
        while ((red_mask != 0) && ((red_mask & 0x01) == 0))
        {
          red_mask>>=1;
          red_shift++;
        }
        green_mask=ximage->green_mask;
        green_shift=0;
        while ((green_mask != 0) && ((green_mask & 0x01) == 0))
        {
          green_mask>>=1;
          green_shift++;
        }
        blue_mask=ximage->blue_mask;
        blue_shift=0;
        while ((blue_mask != 0) && ((blue_mask & 0x01) == 0))
        {
          blue_mask>>=1;
          blue_shift++;
        }
        /*
          Convert X image to DirectClass packets.
        */
        if ((image->colors != 0) && (authentic_colormap != MagickFalse))
          for (y=0; y < (ssize_t) image->rows; y++)
          {
            q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
            if (q == (PixelPacket *) NULL)
              break;
            for (x=0; x < (ssize_t) image->columns; x++)
            {
              pixel=XGetPixel(ximage,(int) x,(int) y);
              index=ConstrainColormapIndex(image,(ssize_t) (pixel >>
                red_shift) & red_mask);
              SetPixelRed(q,ScaleShortToQuantum(colors[(ssize_t) index].red));
              index=ConstrainColormapIndex(image,(ssize_t) (pixel >>
                green_shift) & green_mask);
              SetPixelGreen(q,ScaleShortToQuantum(colors[(ssize_t)
                index].green));
              index=ConstrainColormapIndex(image,(ssize_t) (pixel >>
                blue_shift) & blue_mask);
              SetPixelBlue(q,ScaleShortToQuantum(colors[(ssize_t) index].blue));
              q++;
            }
            if (SyncAuthenticPixels(image,exception) == MagickFalse)
              break;
            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
              image->rows);
            if (status == MagickFalse)
              break;
          }
        else
          for (y=0; y < (ssize_t) image->rows; y++)
          {
            q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
            if (q == (PixelPacket *) NULL)
              break;
            for (x=0; x < (ssize_t) image->columns; x++)
            {
              pixel=XGetPixel(ximage,(int) x,(int) y);
              color=(pixel >> red_shift) & red_mask;
              if (red_mask != 0)
                color=(color*65535UL)/red_mask;
              SetPixelRed(q,ScaleShortToQuantum((unsigned short) color));
              color=(pixel >> green_shift) & green_mask;
              if (green_mask != 0)
                color=(color*65535UL)/green_mask;
              SetPixelGreen(q,ScaleShortToQuantum((unsigned short) color));
              color=(pixel >> blue_shift) & blue_mask;
              if (blue_mask != 0)
                color=(color*65535UL)/blue_mask;
              SetPixelBlue(q,ScaleShortToQuantum((unsigned short) color));
              q++;
            }
            if (SyncAuthenticPixels(image,exception) == MagickFalse)
              break;
            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
              image->rows);
            if (status == MagickFalse)
              break;
          }
        break;
      }
      case PseudoClass:
      {
        /*
          Convert X image to PseudoClass packets.
        */
        if (AcquireImageColormap(image,image->colors) == MagickFalse)
          {
            if (header.ncolors != 0)
              colors=(XColor *) RelinquishMagickMemory(colors);
            ximage->data=DestroyString(ximage->data);
            ximage=(XImage *) RelinquishMagickMemory(ximage);
            ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
          }
        for (i=0; i < (ssize_t) image->colors; i++)
        {
          image->colormap[i].red=ScaleShortToQuantum(colors[i].red);
          image->colormap[i].green=ScaleShortToQuantum(colors[i].green);
          image->colormap[i].blue=ScaleShortToQuantum(colors[i].blue);
        }
        for (y=0; y < (ssize_t) image->rows; y++)
        {
          q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
          if (q == (PixelPacket *) NULL)
            break;
          indexes=GetAuthenticIndexQueue(image);
          for (x=0; x < (ssize_t) image->columns; x++)
          {
            index=ConstrainColormapIndex(image,(ssize_t) XGetPixel(ximage,(int)
              x,(int) y));
            SetPixelIndex(indexes+x,index);
            SetPixelRGBO(q,image->colormap+(ssize_t) index);
            q++;
          }
          if (SyncAuthenticPixels(image,exception) == MagickFalse)
            break;
          status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
            image->rows);
          if (status == MagickFalse)
            break;
        }
        break;
      }
    }
  /*
    Free image and colormap.
  */
  if (header.ncolors != 0)
    colors=(XColor *) RelinquishMagickMemory(colors);
  ximage->data=DestroyString(ximage->data);
  ximage=(XImage *) RelinquishMagickMemory(ximage);
  if (EOFBlob(image) != MagickFalse)
    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
      image->filename);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}


static Image *ReadCINImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
#define MonoColorType  1
#define RGBColorType  3

  char
    property[MagickPathExtent];

  CINInfo
    cin;

  const unsigned char
    *pixels;

  Image
    *image;

  MagickBooleanType
    status;

  MagickOffsetType
    offset;

  QuantumInfo
    *quantum_info;

  QuantumType
    quantum_type;

  register ssize_t
    i;

  register Quantum
    *q;

  size_t
    length;

  ssize_t
    count,
    y;

  unsigned char
    magick[4];

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickCoreSignature);
  image=AcquireImage(image_info,exception);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  /*
    File information.
  */
  offset=0;
  count=ReadBlob(image,4,magick);
  offset+=count;
  if ((count != 4) ||
      ((LocaleNCompare((char *) magick,"\200\052\137\327",4) != 0)))
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  memset(&cin,0,sizeof(cin));
  image->endian=(magick[0] == 0x80) && (magick[1] == 0x2a) &&
    (magick[2] == 0x5f) && (magick[3] == 0xd7) ? MSBEndian : LSBEndian;
  cin.file.image_offset=ReadBlobLong(image);
  offset+=4;
  cin.file.generic_length=ReadBlobLong(image);
  offset+=4;
  cin.file.industry_length=ReadBlobLong(image);
  offset+=4;
  cin.file.user_length=ReadBlobLong(image);
  offset+=4;
  cin.file.file_size=ReadBlobLong(image);
  offset+=4;
  offset+=ReadBlob(image,sizeof(cin.file.version),(unsigned char *)
    cin.file.version);
  (void) CopyMagickString(property,cin.file.version,sizeof(cin.file.version));
  (void) SetImageProperty(image,"dpx:file.version",property,exception);
  offset+=ReadBlob(image,sizeof(cin.file.filename),(unsigned char *)
    cin.file.filename);
  (void) CopyMagickString(property,cin.file.filename,sizeof(cin.file.filename));
  (void) SetImageProperty(image,"dpx:file.filename",property,exception);
  offset+=ReadBlob(image,sizeof(cin.file.create_date),(unsigned char *)
    cin.file.create_date);
  (void) CopyMagickString(property,cin.file.create_date,
    sizeof(cin.file.create_date));
  (void) SetImageProperty(image,"dpx:file.create_date",property,exception);
  offset+=ReadBlob(image,sizeof(cin.file.create_time),(unsigned char *)
    cin.file.create_time);
  (void) CopyMagickString(property,cin.file.create_time,
    sizeof(cin.file.create_time));
  (void) SetImageProperty(image,"dpx:file.create_time",property,exception);
  offset+=ReadBlob(image,sizeof(cin.file.reserve),(unsigned char *)
    cin.file.reserve);
  /*
    Image information.
  */
  cin.image.orientation=(unsigned char) ReadBlobByte(image);
  offset++;
  if (cin.image.orientation != (unsigned char) (~0))
    (void) FormatImageProperty(image,"dpx:image.orientation","%d",
      cin.image.orientation);
  switch (cin.image.orientation)
  {
    default:
    case 0: image->orientation=TopLeftOrientation; break;
    case 1: image->orientation=TopRightOrientation; break;
    case 2: image->orientation=BottomLeftOrientation; break;
    case 3: image->orientation=BottomRightOrientation; break;
    case 4: image->orientation=LeftTopOrientation; break;
    case 5: image->orientation=RightTopOrientation; break;
    case 6: image->orientation=LeftBottomOrientation; break;
    case 7: image->orientation=RightBottomOrientation; break;
  }
  cin.image.number_channels=(unsigned char) ReadBlobByte(image);
  offset++;
  offset+=ReadBlob(image,sizeof(cin.image.reserve1),(unsigned char *)
    cin.image.reserve1);
  for (i=0; i < 8; i++)
  {
    cin.image.channel[i].designator[0]=(unsigned char) ReadBlobByte(image);
    offset++;
    cin.image.channel[i].designator[1]=(unsigned char) ReadBlobByte(image);
    offset++;
    cin.image.channel[i].bits_per_pixel=(unsigned char) ReadBlobByte(image);
    offset++;
    cin.image.channel[i].reserve=(unsigned char) ReadBlobByte(image);
    offset++;
    cin.image.channel[i].pixels_per_line=ReadBlobLong(image);
    offset+=4;
    cin.image.channel[i].lines_per_image=ReadBlobLong(image);
    offset+=4;
    cin.image.channel[i].min_data=ReadBlobFloat(image);
    offset+=4;
    cin.image.channel[i].min_quantity=ReadBlobFloat(image);
    offset+=4;
    cin.image.channel[i].max_data=ReadBlobFloat(image);
    offset+=4;
    cin.image.channel[i].max_quantity=ReadBlobFloat(image);
    offset+=4;
  }
  cin.image.white_point[0]=ReadBlobFloat(image);
  offset+=4;
  if (IsFloatDefined(cin.image.white_point[0]) != MagickFalse)
    image->chromaticity.white_point.x=cin.image.white_point[0];
  cin.image.white_point[1]=ReadBlobFloat(image);
  offset+=4;
  if (IsFloatDefined(cin.image.white_point[1]) != MagickFalse)
    image->chromaticity.white_point.y=cin.image.white_point[1];
  cin.image.red_primary_chromaticity[0]=ReadBlobFloat(image);
  offset+=4;
  if (IsFloatDefined(cin.image.red_primary_chromaticity[0]) != MagickFalse)
    image->chromaticity.red_primary.x=cin.image.red_primary_chromaticity[0];
  cin.image.red_primary_chromaticity[1]=ReadBlobFloat(image);
  offset+=4;
  if (IsFloatDefined(cin.image.red_primary_chromaticity[1]) != MagickFalse)
    image->chromaticity.red_primary.y=cin.image.red_primary_chromaticity[1];
  cin.image.green_primary_chromaticity[0]=ReadBlobFloat(image);
  offset+=4;
  if (IsFloatDefined(cin.image.green_primary_chromaticity[0]) != MagickFalse)
    image->chromaticity.red_primary.x=cin.image.green_primary_chromaticity[0];
  cin.image.green_primary_chromaticity[1]=ReadBlobFloat(image);
  offset+=4;
  if (IsFloatDefined(cin.image.green_primary_chromaticity[1]) != MagickFalse)
    image->chromaticity.green_primary.y=cin.image.green_primary_chromaticity[1];
  cin.image.blue_primary_chromaticity[0]=ReadBlobFloat(image);
  offset+=4;
  if (IsFloatDefined(cin.image.blue_primary_chromaticity[0]) != MagickFalse)
    image->chromaticity.blue_primary.x=cin.image.blue_primary_chromaticity[0];
  cin.image.blue_primary_chromaticity[1]=ReadBlobFloat(image);
  offset+=4;
  if (IsFloatDefined(cin.image.blue_primary_chromaticity[1]) != MagickFalse)
    image->chromaticity.blue_primary.y=cin.image.blue_primary_chromaticity[1];
  offset+=ReadBlob(image,sizeof(cin.image.label),(unsigned char *)
    cin.image.label);
  (void) CopyMagickString(property,cin.image.label,sizeof(cin.image.label));
  (void) SetImageProperty(image,"dpx:image.label",property,exception);
  offset+=ReadBlob(image,sizeof(cin.image.reserve),(unsigned char *)
    cin.image.reserve);
  /*
    Image data format information.
  */
  cin.data_format.interleave=(unsigned char) ReadBlobByte(image);
  offset++;
  cin.data_format.packing=(unsigned char) ReadBlobByte(image);
  offset++;
  cin.data_format.sign=(unsigned char) ReadBlobByte(image);
  offset++;
  cin.data_format.sense=(unsigned char) ReadBlobByte(image);
  offset++;
  cin.data_format.line_pad=ReadBlobLong(image);
  offset+=4;
  cin.data_format.channel_pad=ReadBlobLong(image);
  offset+=4;
  offset+=ReadBlob(image,sizeof(cin.data_format.reserve),(unsigned char *)
    cin.data_format.reserve);
  /*
    Image origination information.
  */
  cin.origination.x_offset=ReadBlobSignedLong(image);
  offset+=4;
  if ((size_t) cin.origination.x_offset != ~0UL)
    (void) FormatImageProperty(image,"dpx:origination.x_offset","%.20g",
      (double) cin.origination.x_offset);
  cin.origination.y_offset=(ssize_t) ReadBlobLong(image);
  offset+=4;
  if ((size_t) cin.origination.y_offset != ~0UL)
    (void) FormatImageProperty(image,"dpx:origination.y_offset","%.20g",
      (double) cin.origination.y_offset);
  offset+=ReadBlob(image,sizeof(cin.origination.filename),(unsigned char *)
    cin.origination.filename);
  (void) CopyMagickString(property,cin.origination.filename,
    sizeof(cin.origination.filename));
  (void) SetImageProperty(image,"dpx:origination.filename",property,exception);
  offset+=ReadBlob(image,sizeof(cin.origination.create_date),(unsigned char *)
    cin.origination.create_date);
  (void) CopyMagickString(property,cin.origination.create_date,
    sizeof(cin.origination.create_date));
  (void) SetImageProperty(image,"dpx:origination.create_date",property,
    exception);
  offset+=ReadBlob(image,sizeof(cin.origination.create_time),(unsigned char *)
    cin.origination.create_time);
  (void) CopyMagickString(property,cin.origination.create_time,
    sizeof(cin.origination.create_time));
  (void) SetImageProperty(image,"dpx:origination.create_time",property,
    exception);
  offset+=ReadBlob(image,sizeof(cin.origination.device),(unsigned char *)
    cin.origination.device);
  (void) CopyMagickString(property,cin.origination.device,
    sizeof(cin.origination.device));
  (void) SetImageProperty(image,"dpx:origination.device",property,exception);
  offset+=ReadBlob(image,sizeof(cin.origination.model),(unsigned char *)
    cin.origination.model);
  (void) CopyMagickString(property,cin.origination.model,
    sizeof(cin.origination.model));
  (void) SetImageProperty(image,"dpx:origination.model",property,exception);
  (void) memset(cin.origination.serial,0,
    sizeof(cin.origination.serial));
  offset+=ReadBlob(image,sizeof(cin.origination.serial),(unsigned char *)
    cin.origination.serial);
  (void) CopyMagickString(property,cin.origination.serial,
    sizeof(cin.origination.serial));
  (void) SetImageProperty(image,"dpx:origination.serial",property,exception);
  cin.origination.x_pitch=ReadBlobFloat(image);
  offset+=4;
  cin.origination.y_pitch=ReadBlobFloat(image);
  offset+=4;
  cin.origination.gamma=ReadBlobFloat(image);
  offset+=4;
  if (IsFloatDefined(cin.origination.gamma) != MagickFalse)
    image->gamma=cin.origination.gamma;
  offset+=ReadBlob(image,sizeof(cin.origination.reserve),(unsigned char *)
    cin.origination.reserve);
  if ((cin.file.image_offset > 2048) && (cin.file.user_length != 0))
    {
      int
        c;

      /*
        Image film information.
      */
      cin.film.id=ReadBlobByte(image);
      offset++;
      c=cin.film.id;
      if (c != ~0)
        (void) FormatImageProperty(image,"dpx:film.id","%d",cin.film.id);
      cin.film.type=ReadBlobByte(image);
      offset++;
      c=cin.film.type;
      if (c != ~0)
        (void) FormatImageProperty(image,"dpx:film.type","%d",cin.film.type);
      cin.film.offset=ReadBlobByte(image);
      offset++;
      c=cin.film.offset;
      if (c != ~0)
        (void) FormatImageProperty(image,"dpx:film.offset","%d",
          cin.film.offset);
      cin.film.reserve1=ReadBlobByte(image);
      offset++;
      cin.film.prefix=ReadBlobLong(image);
      offset+=4;
      if (cin.film.prefix != ~0UL)
        (void) FormatImageProperty(image,"dpx:film.prefix","%.20g",(double)
          cin.film.prefix);
      cin.film.count=ReadBlobLong(image);
      offset+=4;
      offset+=ReadBlob(image,sizeof(cin.film.format),(unsigned char *)
        cin.film.format);
      (void) CopyMagickString(property,cin.film.format,sizeof(cin.film.format));
      (void) SetImageProperty(image,"dpx:film.format",property,exception);
      cin.film.frame_position=ReadBlobLong(image);
      offset+=4;
      if (cin.film.frame_position != ~0UL)
        (void) FormatImageProperty(image,"dpx:film.frame_position","%.20g",
          (double) cin.film.frame_position);
      cin.film.frame_rate=ReadBlobFloat(image);
      offset+=4;
      if (IsFloatDefined(cin.film.frame_rate) != MagickFalse)
        (void) FormatImageProperty(image,"dpx:film.frame_rate","%g",
          cin.film.frame_rate);
      offset+=ReadBlob(image,sizeof(cin.film.frame_id),(unsigned char *)
        cin.film.frame_id);
      (void) CopyMagickString(property,cin.film.frame_id,
        sizeof(cin.film.frame_id));
      (void) SetImageProperty(image,"dpx:film.frame_id",property,exception);
      offset+=ReadBlob(image,sizeof(cin.film.slate_info),(unsigned char *)
        cin.film.slate_info);
      (void) CopyMagickString(property,cin.film.slate_info,
        sizeof(cin.film.slate_info));
      (void) SetImageProperty(image,"dpx:film.slate_info",property,exception);
      offset+=ReadBlob(image,sizeof(cin.film.reserve),(unsigned char *)
        cin.film.reserve);
    }
  if ((cin.file.image_offset > 2048) && (cin.file.user_length != 0))
    {
      StringInfo
        *profile;

      /*
        User defined data.
      */
      if (cin.file.user_length > GetBlobSize(image))
        ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
      profile=BlobToStringInfo((const unsigned char *) NULL,
        cin.file.user_length);
      if (profile == (StringInfo *) NULL)
        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
      offset+=ReadBlob(image,GetStringInfoLength(profile),
        GetStringInfoDatum(profile));
      (void) SetImageProfile(image,"dpx:user.data",profile,exception);
      profile=DestroyStringInfo(profile);
    }
  image->depth=cin.image.channel[0].bits_per_pixel;
  image->columns=cin.image.channel[0].pixels_per_line;
  image->rows=cin.image.channel[0].lines_per_image;
  if (image_info->ping != MagickFalse)
    {
      (void) CloseBlob(image);
      return(image);
    }
  if (((MagickSizeType) image->columns*image->rows) > GetBlobSize(image))
    ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
  for ( ; offset < (MagickOffsetType) cin.file.image_offset; offset++)
  {
    int
      c;

    c=ReadBlobByte(image);
    if (c == EOF)
      break;
  }
  if (offset < (MagickOffsetType) cin.file.image_offset)
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  status=SetImageExtent(image,image->columns,image->rows,exception);
  if (status == MagickFalse)
    return(DestroyImageList(image));
  (void) SetImageBackgroundColor(image,exception);
  /*
    Convert CIN raster image to pixel packets.
  */
  quantum_info=AcquireQuantumInfo(image_info,image);
  if (quantum_info == (QuantumInfo *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  quantum_info->quantum=32;
  quantum_info->pack=MagickFalse;
  quantum_type=RGBQuantum;
  length=GetQuantumExtent(image,quantum_info,quantum_type);
  length=GetBytesPerRow(image->columns,3,image->depth,MagickTrue);
  if (cin.image.number_channels == 1)
    {
      quantum_type=GrayQuantum;
      length=GetBytesPerRow(image->columns,1,image->depth,MagickTrue);
    }
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    if (q == (Quantum *) NULL)
      break;
    pixels=(const unsigned char *) ReadBlobStream(image,length,
      GetQuantumPixels(quantum_info),&count);
    if ((size_t) count != length)
      break;
    (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
      quantum_type,pixels,exception);
    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      break;
    if (image->previous == (Image *) NULL)
      {
        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
          image->rows);
        if (status == MagickFalse)
          break;
      }
  }
  SetQuantumImageType(image,quantum_type);
  quantum_info=DestroyQuantumInfo(quantum_info);
  if (EOFBlob(image) != MagickFalse)
    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
      image->filename);
  SetImageColorspace(image,LogColorspace,exception);
  (void) CloseBlob(image);
  return(GetFirstImageInList(image));
}


ModuleExport size_t RegisterCINImage(void)
{
  MagickInfo
    *entry;

  entry=SetMagickInfo("CIN");
  entry->decoder=(DecodeImageHandler *) ReadCINImage;
  entry->encoder=(EncodeImageHandler *) WriteCINImage;
  entry->magick=(IsImageFormatHandler *) IsCIN;
  entry->adjoin=MagickFalse;
  entry->seekable_stream=MagickTrue;
  entry->description=ConstantString("Cineon Image File");
  entry->module=ConstantString("CIN");
  (void) RegisterMagickInfo(entry);
  return(MagickImageCoderSignature);
}


static inline const char *GetCINProperty(const ImageInfo *image_info,
  const Image *image,const char *property)
{
  const char
    *value;

  value=GetImageOption(image_info,property);
  if (value != (const char *) NULL)
    return(value);
  return(GetImageProperty(image,property));
}


static int incrAggDepth(Walker *pWalker, Expr *pExpr){
  if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
  return WRC_Continue;
}


void rds_tcp_reset_callbacks(struct socket *sock,
			     struct rds_conn_path *cp)
{
	struct rds_tcp_connection *tc = cp->cp_transport_data;
	struct socket *osock = tc->t_sock;

	if (!osock)
		goto newsock;

	/* Need to resolve a duelling SYN between peers.
	 * We have an outstanding SYN to this peer, which may
	 * potentially have transitioned to the RDS_CONN_UP state,
	 * so we must quiesce any send threads before resetting
	 * cp_transport_data. We quiesce these threads by setting
	 * cp_state to something other than RDS_CONN_UP, and then
	 * waiting for any existing threads in rds_send_xmit to
	 * complete release_in_xmit(). (Subsequent threads entering
	 * rds_send_xmit() will bail on !rds_conn_up().
	 *
	 * However an incoming syn-ack at this point would end up
	 * marking the conn as RDS_CONN_UP, and would again permit
	 * rds_send_xmi() threads through, so ideally we would
	 * synchronize on RDS_CONN_UP after lock_sock(), but cannot
	 * do that: waiting on !RDS_IN_XMIT after lock_sock() may
	 * end up deadlocking with tcp_sendmsg(), and the RDS_IN_XMIT
	 * would not get set. As a result, we set c_state to
	 * RDS_CONN_RESETTTING, to ensure that rds_tcp_state_change
	 * cannot mark rds_conn_path_up() in the window before lock_sock()
	 */
	atomic_set(&cp->cp_state, RDS_CONN_RESETTING);
	wait_event(cp->cp_waitq, !test_bit(RDS_IN_XMIT, &cp->cp_flags));
	lock_sock(osock->sk);
	/* reset receive side state for rds_tcp_data_recv() for osock  */
	cancel_delayed_work_sync(&cp->cp_send_w);
	cancel_delayed_work_sync(&cp->cp_recv_w);
	if (tc->t_tinc) {
		rds_inc_put(&tc->t_tinc->ti_inc);
		tc->t_tinc = NULL;
	}
	tc->t_tinc_hdr_rem = sizeof(struct rds_header);
	tc->t_tinc_data_rem = 0;
	rds_tcp_restore_callbacks(osock, tc);
	release_sock(osock->sk);
	sock_release(osock);
newsock:
	rds_send_path_reset(cp);
	lock_sock(sock->sk);
	rds_tcp_set_callbacks(sock, cp);
	release_sock(sock->sk);
}


adv_error adv_png_read(
	unsigned* pix_width, unsigned* pix_height, unsigned* pix_pixel,
	unsigned char** dat_ptr, unsigned* dat_size,
	unsigned char** pix_ptr, unsigned* pix_scanline,
	unsigned char** pal_ptr, unsigned* pal_size,
	adv_fz* f)
{
	adv_error r;
	unsigned char* rns_ptr;
	unsigned rns_size;

	r = adv_png_read_rns(pix_width, pix_height, pix_pixel, dat_ptr, dat_size, pix_ptr, pix_scanline, pal_ptr, pal_size, &rns_ptr, &rns_size, f);

	if (r == 0)
		free(rns_ptr);

	return r;
}


adv_error adv_png_write_ihdr(
	unsigned pix_width, unsigned pix_height,
	unsigned pix_depth, unsigned pix_type,
	adv_fz* f, unsigned* count)
{
	uint8 ihdr[13];

	be_uint32_write(ihdr, pix_width);
	be_uint32_write(ihdr+4, pix_height);

	ihdr[8] = pix_depth;
	ihdr[9] = pix_type;
	ihdr[10] = 0; /* compression */
	ihdr[11] = 0; /* filter */
	ihdr[12] = 0; /* interlace */

	if (adv_png_write_chunk(f, ADV_PNG_CN_IHDR, ihdr, 13, count)!=0)
		return -1;

	return 0;
}


void adv_png_unfilter_8(unsigned width, unsigned height, unsigned char* p, unsigned line)
{
	unsigned i, j;

	for(i=0;i<height;++i) {
		unsigned char f = *p++;

		if (f == 0) { /* none */
			p += width;
		} else if (f == 1) { /* sub */
			++p;
			for(j=1;j<width;++j) {
				p[0] += p[-1];
				++p;
			}
		} else if (f == 2) { /* up */
			if (i) {
				unsigned char* u = p - line;
				for(j=0;j<width;++j) {
					*p += *u;
					++p;
					++u;
				}
			} else {
				p += width;
			}
		} else if (f == 3) { /* average */
			if (i) {
				unsigned char* u = p - line;
				p[0] += u[0] / 2;
				++p;
				++u;
				for(j=1;j<width;++j) {
					unsigned a = (unsigned)u[0] + (unsigned)p[-1];
					p[0] += a >> 1;
					++p;
					++u;
				}
			} else {
				++p;
				for(j=1;j<width;++j) {
					p[0] += p[-1] / 2;
					++p;
				}
			}
		} else if (f == 4) { /* paeth */
			unsigned char* u = p - line;
			for(j=0;j<width;++j) {
				unsigned a, b, c;
				int v;
				int da, db, dc;
				a = j<1 ? 0 : p[-1];
				b = i<1 ? 0 : u[0];
				c = (j<1 || i<1) ? 0 : u[-1];
				v = a + b - c;
				da = v - a;
				if (da < 0)
					da = -da;
				db = v - b;
				if (db < 0)
					db = -db;
				dc = v - c;
				if (dc < 0)
					dc = -dc;
				if (da <= db && da <= dc)
					p[0] += a;
				else if (db <= dc)
					p[0] += b;
				else
					p[0] += c;
				++p;
				++u;
			}
		}

		p += line - width - 1;
	}
}


adv_error adv_png_write(
	unsigned pix_width, unsigned pix_height, unsigned pix_pixel,
	const unsigned char* pix_ptr, int pix_pixel_pitch, int pix_scanline_pitch,
	const unsigned char* pal_ptr, unsigned pal_size,
	adv_bool fast,
	adv_fz* f, unsigned* count)
{
	if (adv_png_write_signature(f, count) != 0) {
		return -1;
	}

	return adv_png_write_raw(
		pix_width, pix_height, pix_pixel,
		pix_ptr, pix_pixel_pitch, pix_scanline_pitch,
		pal_ptr, pal_size,
		0, 0,
		fast,
		f, count
	);
}


PHP_METHOD(imagickkernel, getmatrix)
{
	php_imagickkernel_object *internp;

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

	internp = Z_IMAGICKKERNEL_P(getThis());
	IMAGICK_KERNEL_NOT_NULL_EMPTY(internp);

	array_init(return_value);
	php_imagickkernelvalues_to_zval(return_value, internp->kernel_info);

	return;
}


int megasas_update_device_list(struct megasas_instance *instance,
			       int event_type)
{
	int dcmd_ret = DCMD_SUCCESS;

	if (instance->enable_fw_dev_list) {
		dcmd_ret = megasas_host_device_list_query(instance, false);
		if (dcmd_ret != DCMD_SUCCESS)
			goto out;
	} else {
		if (event_type & SCAN_PD_CHANNEL) {
			dcmd_ret = megasas_get_pd_list(instance);

			if (dcmd_ret != DCMD_SUCCESS)
				goto out;
		}

		if (event_type & SCAN_VD_CHANNEL) {
			if (!instance->requestorId ||
			    (instance->requestorId &&
			     megasas_get_ld_vf_affiliation(instance, 0))) {
				dcmd_ret = megasas_ld_list_query(instance,
						MR_LD_QUERY_TYPE_EXPOSED_TO_HOST);
				if (dcmd_ret != DCMD_SUCCESS)
					goto out;
			}
		}
	}

out:
	return dcmd_ret;
}


megasas_disable_intr_ppc(struct megasas_instance *instance)
{
	struct megasas_register_set __iomem *regs;
	u32 mask = 0xFFFFFFFF;

	regs = instance->reg_set;
	writel(mask, &regs->outbound_intr_mask);
	/* Dummy readl to force pci flush */
	readl(&regs->outbound_intr_mask);
}


megasas_get_ctrl_info(struct megasas_instance *instance)
{
	int ret = 0;
	struct megasas_cmd *cmd;
	struct megasas_dcmd_frame *dcmd;
	struct megasas_ctrl_info *ci;
	dma_addr_t ci_h = 0;

	ci = instance->ctrl_info_buf;
	ci_h = instance->ctrl_info_buf_h;

	cmd = megasas_get_cmd(instance);

	if (!cmd) {
		dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get a free cmd\n");
		return -ENOMEM;
	}

	dcmd = &cmd->frame->dcmd;

	memset(ci, 0, sizeof(*ci));
	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);

	dcmd->cmd = MFI_CMD_DCMD;
	dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
	dcmd->sge_count = 1;
	dcmd->flags = MFI_FRAME_DIR_READ;
	dcmd->timeout = 0;
	dcmd->pad_0 = 0;
	dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_ctrl_info));
	dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_GET_INFO);
	dcmd->mbox.b[0] = 1;

	megasas_set_dma_settings(instance, dcmd, ci_h,
				 sizeof(struct megasas_ctrl_info));

	if ((instance->adapter_type != MFI_SERIES) &&
	    !instance->mask_interrupts) {
		ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
	} else {
		ret = megasas_issue_polled(instance, cmd);
		cmd->flags |= DRV_DCMD_SKIP_REFIRE;
	}

	switch (ret) {
	case DCMD_SUCCESS:
		/* Save required controller information in
		 * CPU endianness format.
		 */
		le32_to_cpus((u32 *)&ci->properties.OnOffProperties);
		le16_to_cpus((u16 *)&ci->properties.on_off_properties2);
		le32_to_cpus((u32 *)&ci->adapterOperations2);
		le32_to_cpus((u32 *)&ci->adapterOperations3);
		le16_to_cpus((u16 *)&ci->adapter_operations4);

		/* Update the latest Ext VD info.
		 * From Init path, store current firmware details.
		 * From OCR path, detect any firmware properties changes.
		 * in case of Firmware upgrade without system reboot.
		 */
		megasas_update_ext_vd_details(instance);
		instance->use_seqnum_jbod_fp =
			ci->adapterOperations3.useSeqNumJbodFP;
		instance->support_morethan256jbod =
			ci->adapter_operations4.support_pd_map_target_id;
		instance->support_nvme_passthru =
			ci->adapter_operations4.support_nvme_passthru;
		instance->task_abort_tmo = ci->TaskAbortTO;
		instance->max_reset_tmo = ci->MaxResetTO;

		/*Check whether controller is iMR or MR */
		instance->is_imr = (ci->memory_size ? 0 : 1);

		instance->snapdump_wait_time =
			(ci->properties.on_off_properties2.enable_snap_dump ?
			 MEGASAS_DEFAULT_SNAP_DUMP_WAIT_TIME : 0);

		instance->enable_fw_dev_list =
			ci->properties.on_off_properties2.enable_fw_dev_list;

		dev_info(&instance->pdev->dev,
			"controller type\t: %s(%dMB)\n",
			instance->is_imr ? "iMR" : "MR",
			le16_to_cpu(ci->memory_size));

		instance->disableOnlineCtrlReset =
			ci->properties.OnOffProperties.disableOnlineCtrlReset;
		instance->secure_jbod_support =
			ci->adapterOperations3.supportSecurityonJBOD;
		dev_info(&instance->pdev->dev, "Online Controller Reset(OCR)\t: %s\n",
			instance->disableOnlineCtrlReset ? "Disabled" : "Enabled");
		dev_info(&instance->pdev->dev, "Secure JBOD support\t: %s\n",
			instance->secure_jbod_support ? "Yes" : "No");
		dev_info(&instance->pdev->dev, "NVMe passthru support\t: %s\n",
			 instance->support_nvme_passthru ? "Yes" : "No");
		dev_info(&instance->pdev->dev,
			 "FW provided TM TaskAbort/Reset timeout\t: %d secs/%d secs\n",
			 instance->task_abort_tmo, instance->max_reset_tmo);

		break;

	case DCMD_TIMEOUT:
		switch (dcmd_timeout_ocr_possible(instance)) {
		case INITIATE_OCR:
			cmd->flags |= DRV_DCMD_SKIP_REFIRE;
			megasas_reset_fusion(instance->host,
				MFI_IO_TIMEOUT_OCR);
			break;
		case KILL_ADAPTER:
			megaraid_sas_kill_hba(instance);
			break;
		case IGNORE_TIMEOUT:
			dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
				__func__, __LINE__);
			break;
		}
		break;
	case DCMD_FAILED:
		megaraid_sas_kill_hba(instance);
		break;

	}

	if (ret != DCMD_TIMEOUT)
		megasas_return_cmd(instance, cmd);

	return ret;
}


megasas_dump_frame(void *mpi_request, int sz)
{
	int i;
	__le32 *mfp = (__le32 *)mpi_request;

	printk(KERN_INFO "IO request frame:\n\t");
	for (i = 0; i < sz / sizeof(__le32); i++) {
		if (i && ((i % 8) == 0))
			printk("\n\t");
		printk("%08x ", le32_to_cpu(mfp[i]));
	}
	printk("\n");
}


static void megasas_flush_cache(struct megasas_instance *instance)
{
	struct megasas_cmd *cmd;
	struct megasas_dcmd_frame *dcmd;

	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)
		return;

	cmd = megasas_get_cmd(instance);

	if (!cmd)
		return;

	dcmd = &cmd->frame->dcmd;

	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);

	dcmd->cmd = MFI_CMD_DCMD;
	dcmd->cmd_status = 0x0;
	dcmd->sge_count = 0;
	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_NONE);
	dcmd->timeout = 0;
	dcmd->pad_0 = 0;
	dcmd->data_xfer_len = 0;
	dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_CACHE_FLUSH);
	dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;

	if (megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS)
			!= DCMD_SUCCESS) {
		dev_err(&instance->pdev->dev,
			"return from %s %d\n", __func__, __LINE__);
		return;
	}

	megasas_return_cmd(instance, cmd);
}


megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
		   struct megasas_cmd *cmd)
{
	u32 is_logical;
	u32 device_id;
	u16 flags = 0;
	struct megasas_pthru_frame *pthru;

	is_logical = MEGASAS_IS_LOGICAL(scp->device);
	device_id = MEGASAS_DEV_INDEX(scp);
	pthru = (struct megasas_pthru_frame *)cmd->frame;

	if (scp->sc_data_direction == DMA_TO_DEVICE)
		flags = MFI_FRAME_DIR_WRITE;
	else if (scp->sc_data_direction == DMA_FROM_DEVICE)
		flags = MFI_FRAME_DIR_READ;
	else if (scp->sc_data_direction == DMA_NONE)
		flags = MFI_FRAME_DIR_NONE;

	if (instance->flag_ieee == 1) {
		flags |= MFI_FRAME_IEEE;
	}

	/*
	 * Prepare the DCDB frame
	 */
	pthru->cmd = (is_logical) ? MFI_CMD_LD_SCSI_IO : MFI_CMD_PD_SCSI_IO;
	pthru->cmd_status = 0x0;
	pthru->scsi_status = 0x0;
	pthru->target_id = device_id;
	pthru->lun = scp->device->lun;
	pthru->cdb_len = scp->cmd_len;
	pthru->timeout = 0;
	pthru->pad_0 = 0;
	pthru->flags = cpu_to_le16(flags);
	pthru->data_xfer_len = cpu_to_le32(scsi_bufflen(scp));

	memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);

	/*
	 * If the command is for the tape device, set the
	 * pthru timeout to the os layer timeout value.
	 */
	if (scp->device->type == TYPE_TAPE) {
		if ((scp->request->timeout / HZ) > 0xFFFF)
			pthru->timeout = cpu_to_le16(0xFFFF);
		else
			pthru->timeout = cpu_to_le16(scp->request->timeout / HZ);
	}

	/*
	 * Construct SGL
	 */
	if (instance->flag_ieee == 1) {
		pthru->flags |= cpu_to_le16(MFI_FRAME_SGL64);
		pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
						      &pthru->sgl);
	} else if (IS_DMA64) {
		pthru->flags |= cpu_to_le16(MFI_FRAME_SGL64);
		pthru->sge_count = megasas_make_sgl64(instance, scp,
						      &pthru->sgl);
	} else
		pthru->sge_count = megasas_make_sgl32(instance, scp,
						      &pthru->sgl);

	if (pthru->sge_count > instance->max_num_sge) {
		dev_err(&instance->pdev->dev, "DCDB too many SGE NUM=%x\n",
			pthru->sge_count);
		return 0;
	}

	/*
	 * Sense info specific
	 */
	pthru->sense_len = SCSI_SENSE_BUFFERSIZE;
	pthru->sense_buf_phys_addr_hi =
		cpu_to_le32(upper_32_bits(cmd->sense_phys_addr));
	pthru->sense_buf_phys_addr_lo =
		cpu_to_le32(lower_32_bits(cmd->sense_phys_addr));

	/*
	 * Compute the total number of frames this command consumes. FW uses
	 * this number to pull sufficient number of frames from host memory.
	 */
	cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
							PTHRU_FRAME);

	return cmd->frame_count;
}


megasas_adp_reset_xscale(struct megasas_instance *instance,
	struct megasas_register_set __iomem *regs)
{
	u32 i;
	u32 pcidata;

	writel(MFI_ADP_RESET, &regs->inbound_doorbell);

	for (i = 0; i < 3; i++)
		msleep(1000); /* sleep for 3 secs */
	pcidata  = 0;
	pci_read_config_dword(instance->pdev, MFI_1068_PCSR_OFFSET, &pcidata);
	dev_notice(&instance->pdev->dev, "pcidata = %x\n", pcidata);
	if (pcidata & 0x2) {
		dev_notice(&instance->pdev->dev, "mfi 1068 offset read=%x\n", pcidata);
		pcidata &= ~0x2;
		pci_write_config_dword(instance->pdev,
				MFI_1068_PCSR_OFFSET, pcidata);

		for (i = 0; i < 2; i++)
			msleep(1000); /* need to wait 2 secs again */

		pcidata  = 0;
		pci_read_config_dword(instance->pdev,
				MFI_1068_FW_HANDSHAKE_OFFSET, &pcidata);
		dev_notice(&instance->pdev->dev, "1068 offset handshake read=%x\n", pcidata);
		if ((pcidata & 0xffff0000) == MFI_1068_FW_READY) {
			dev_notice(&instance->pdev->dev, "1068 offset pcidt=%x\n", pcidata);
			pcidata = 0;
			pci_write_config_dword(instance->pdev,
				MFI_1068_FW_HANDSHAKE_OFFSET, pcidata);
		}
	}
	return 0;
}


megasas_check_reset_ppc(struct megasas_instance *instance,
			struct megasas_register_set __iomem *regs)
{
	if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
		return 1;

	return 0;
}


megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
		      struct megasas_iocpacket __user * user_ioc,
		      struct megasas_iocpacket *ioc)
{
	struct megasas_sge64 *kern_sge64 = NULL;
	struct megasas_sge32 *kern_sge32 = NULL;
	struct megasas_cmd *cmd;
	void *kbuff_arr[MAX_IOCTL_SGE];
	dma_addr_t buf_handle = 0;
	int error = 0, i;
	void *sense = NULL;
	dma_addr_t sense_handle;
	unsigned long *sense_ptr;
	u32 opcode = 0;

	memset(kbuff_arr, 0, sizeof(kbuff_arr));

	if (ioc->sge_count > MAX_IOCTL_SGE) {
		dev_printk(KERN_DEBUG, &instance->pdev->dev, "SGE count [%d] >  max limit [%d]\n",
		       ioc->sge_count, MAX_IOCTL_SGE);
		return -EINVAL;
	}

	if ((ioc->frame.hdr.cmd >= MFI_CMD_OP_COUNT) ||
	    ((ioc->frame.hdr.cmd == MFI_CMD_NVME) &&
	    !instance->support_nvme_passthru)) {
		dev_err(&instance->pdev->dev,
			"Received invalid ioctl command 0x%x\n",
			ioc->frame.hdr.cmd);
		return -ENOTSUPP;
	}

	cmd = megasas_get_cmd(instance);
	if (!cmd) {
		dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get a cmd packet\n");
		return -ENOMEM;
	}

	/*
	 * User's IOCTL packet has 2 frames (maximum). Copy those two
	 * frames into our cmd's frames. cmd->frame's context will get
	 * overwritten when we copy from user's frames. So set that value
	 * alone separately
	 */
	memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
	cmd->frame->hdr.context = cpu_to_le32(cmd->index);
	cmd->frame->hdr.pad_0 = 0;

	cmd->frame->hdr.flags &= (~MFI_FRAME_IEEE);

	if (instance->consistent_mask_64bit)
		cmd->frame->hdr.flags |= cpu_to_le16((MFI_FRAME_SGL64 |
				       MFI_FRAME_SENSE64));
	else
		cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_SGL64 |
					       MFI_FRAME_SENSE64));

	if (cmd->frame->hdr.cmd == MFI_CMD_DCMD)
		opcode = le32_to_cpu(cmd->frame->dcmd.opcode);

	if (opcode == MR_DCMD_CTRL_SHUTDOWN) {
		if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) {
			megasas_return_cmd(instance, cmd);
			return -1;
		}
	}

	if (opcode == MR_DRIVER_SET_APP_CRASHDUMP_MODE) {
		error = megasas_set_crash_dump_params_ioctl(cmd);
		megasas_return_cmd(instance, cmd);
		return error;
	}

	/*
	 * The management interface between applications and the fw uses
	 * MFI frames. E.g, RAID configuration changes, LD property changes
	 * etc are accomplishes through different kinds of MFI frames. The
	 * driver needs to care only about substituting user buffers with
	 * kernel buffers in SGLs. The location of SGL is embedded in the
	 * struct iocpacket itself.
	 */
	if (instance->consistent_mask_64bit)
		kern_sge64 = (struct megasas_sge64 *)
			((unsigned long)cmd->frame + ioc->sgl_off);
	else
		kern_sge32 = (struct megasas_sge32 *)
			((unsigned long)cmd->frame + ioc->sgl_off);

	/*
	 * For each user buffer, create a mirror buffer and copy in
	 */
	for (i = 0; i < ioc->sge_count; i++) {
		if (!ioc->sgl[i].iov_len)
			continue;

		kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev,
						    ioc->sgl[i].iov_len,
						    &buf_handle, GFP_KERNEL);
		if (!kbuff_arr[i]) {
			dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to alloc "
			       "kernel SGL buffer for IOCTL\n");
			error = -ENOMEM;
			goto out;
		}

		/*
		 * We don't change the dma_coherent_mask, so
		 * dma_alloc_coherent only returns 32bit addresses
		 */
		if (instance->consistent_mask_64bit) {
			kern_sge64[i].phys_addr = cpu_to_le64(buf_handle);
			kern_sge64[i].length = cpu_to_le32(ioc->sgl[i].iov_len);
		} else {
			kern_sge32[i].phys_addr = cpu_to_le32(buf_handle);
			kern_sge32[i].length = cpu_to_le32(ioc->sgl[i].iov_len);
		}

		/*
		 * We created a kernel buffer corresponding to the
		 * user buffer. Now copy in from the user buffer
		 */
		if (copy_from_user(kbuff_arr[i], ioc->sgl[i].iov_base,
				   (u32) (ioc->sgl[i].iov_len))) {
			error = -EFAULT;
			goto out;
		}
	}

	if (ioc->sense_len) {
		sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len,
					     &sense_handle, GFP_KERNEL);
		if (!sense) {
			error = -ENOMEM;
			goto out;
		}

		sense_ptr =
		(unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
		if (instance->consistent_mask_64bit)
			*sense_ptr = cpu_to_le64(sense_handle);
		else
			*sense_ptr = cpu_to_le32(sense_handle);
	}

	/*
	 * Set the sync_cmd flag so that the ISR knows not to complete this
	 * cmd to the SCSI mid-layer
	 */
	cmd->sync_cmd = 1;
	if (megasas_issue_blocked_cmd(instance, cmd, 0) == DCMD_NOT_FIRED) {
		cmd->sync_cmd = 0;
		dev_err(&instance->pdev->dev,
			"return -EBUSY from %s %d cmd 0x%x opcode 0x%x cmd->cmd_status_drv 0x%x\n",
			__func__, __LINE__, cmd->frame->hdr.cmd, opcode,
			cmd->cmd_status_drv);
		return -EBUSY;
	}

	cmd->sync_cmd = 0;

	if (instance->unload == 1) {
		dev_info(&instance->pdev->dev, "Driver unload is in progress "
			"don't submit data to application\n");
		goto out;
	}
	/*
	 * copy out the kernel buffers to user buffers
	 */
	for (i = 0; i < ioc->sge_count; i++) {
		if (copy_to_user(ioc->sgl[i].iov_base, kbuff_arr[i],
				 ioc->sgl[i].iov_len)) {
			error = -EFAULT;
			goto out;
		}
	}

	/*
	 * copy out the sense
	 */
	if (ioc->sense_len) {
		/*
		 * sense_ptr points to the location that has the user
		 * sense buffer address
		 */
		sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
				ioc->sense_off);

		if (copy_to_user((void __user *)((unsigned long)
				 get_unaligned((unsigned long *)sense_ptr)),
				 sense, ioc->sense_len)) {
			dev_err(&instance->pdev->dev, "Failed to copy out to user "
					"sense data\n");
			error = -EFAULT;
			goto out;
		}
	}

	/*
	 * copy the status codes returned by the fw
	 */
	if (copy_to_user(&user_ioc->frame.hdr.cmd_status,
			 &cmd->frame->hdr.cmd_status, sizeof(u8))) {
		dev_printk(KERN_DEBUG, &instance->pdev->dev, "Error copying out cmd_status\n");
		error = -EFAULT;
	}

out:
	if (sense) {
		dma_free_coherent(&instance->pdev->dev, ioc->sense_len,
				    sense, sense_handle);
	}

	for (i = 0; i < ioc->sge_count; i++) {
		if (kbuff_arr[i]) {
			if (instance->consistent_mask_64bit)
				dma_free_coherent(&instance->pdev->dev,
					le32_to_cpu(kern_sge64[i].length),
					kbuff_arr[i],
					le64_to_cpu(kern_sge64[i].phys_addr));
			else
				dma_free_coherent(&instance->pdev->dev,
					le32_to_cpu(kern_sge32[i].length),
					kbuff_arr[i],
					le32_to_cpu(kern_sge32[i].phys_addr));
			kbuff_arr[i] = NULL;
		}
	}

	megasas_return_cmd(instance, cmd);
	return error;
}


megasas_issue_init_mfi(struct megasas_instance *instance)
{
	__le32 context;
	struct megasas_cmd *cmd;
	struct megasas_init_frame *init_frame;
	struct megasas_init_queue_info *initq_info;
	dma_addr_t init_frame_h;
	dma_addr_t initq_info_h;

	/*
	 * Prepare a init frame. Note the init frame points to queue info
	 * structure. Each frame has SGL allocated after first 64 bytes. For
	 * this frame - since we don't need any SGL - we use SGL's space as
	 * queue info structure
	 *
	 * We will not get a NULL command below. We just created the pool.
	 */
	cmd = megasas_get_cmd(instance);

	init_frame = (struct megasas_init_frame *)cmd->frame;
	initq_info = (struct megasas_init_queue_info *)
		((unsigned long)init_frame + 64);

	init_frame_h = cmd->frame_phys_addr;
	initq_info_h = init_frame_h + 64;

	context = init_frame->context;
	memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
	memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
	init_frame->context = context;

	initq_info->reply_queue_entries = cpu_to_le32(instance->max_fw_cmds + 1);
	initq_info->reply_queue_start_phys_addr_lo = cpu_to_le32(instance->reply_queue_h);

	initq_info->producer_index_phys_addr_lo = cpu_to_le32(instance->producer_h);
	initq_info->consumer_index_phys_addr_lo = cpu_to_le32(instance->consumer_h);

	init_frame->cmd = MFI_CMD_INIT;
	init_frame->cmd_status = MFI_STAT_INVALID_STATUS;
	init_frame->queue_info_new_phys_addr_lo =
		cpu_to_le32(lower_32_bits(initq_info_h));
	init_frame->queue_info_new_phys_addr_hi =
		cpu_to_le32(upper_32_bits(initq_info_h));

	init_frame->data_xfer_len = cpu_to_le32(sizeof(struct megasas_init_queue_info));

	/*
	 * disable the intr before firing the init frame to FW
	 */
	instance->instancet->disable_intr(instance);

	/*
	 * Issue the init frame in polled mode
	 */

	if (megasas_issue_polled(instance, cmd)) {
		dev_err(&instance->pdev->dev, "Failed to init firmware\n");
		megasas_return_cmd(instance, cmd);
		goto fail_fw_init;
	}

	megasas_return_cmd(instance, cmd);

	return 0;

fail_fw_init:
	return -EINVAL;
}


void megasas_set_dma_settings(struct megasas_instance *instance,
			      struct megasas_dcmd_frame *dcmd,
			      dma_addr_t dma_addr, u32 dma_len)
{
	if (instance->consistent_mask_64bit) {
		dcmd->sgl.sge64[0].phys_addr = cpu_to_le64(dma_addr);
		dcmd->sgl.sge64[0].length = cpu_to_le32(dma_len);
		dcmd->flags = cpu_to_le16(dcmd->flags | MFI_FRAME_SGL64);

	} else {
		dcmd->sgl.sge32[0].phys_addr =
				cpu_to_le32(lower_32_bits(dma_addr));
		dcmd->sgl.sge32[0].length = cpu_to_le32(dma_len);
		dcmd->flags = cpu_to_le16(dcmd->flags);
	}
}


static int megasas_get_ld_vf_affiliation_12(struct megasas_instance *instance,
					    int initial)
{
	struct megasas_cmd *cmd;
	struct megasas_dcmd_frame *dcmd;
	struct MR_LD_VF_AFFILIATION *new_affiliation = NULL;
	struct MR_LD_VF_MAP *newmap = NULL, *savedmap = NULL;
	dma_addr_t new_affiliation_h;
	int i, j, retval = 0, found = 0, doscan = 0;
	u8 thisVf;

	cmd = megasas_get_cmd(instance);

	if (!cmd) {
		dev_printk(KERN_DEBUG, &instance->pdev->dev, "megasas_get_ld_vf_affiliation12: "
		       "Failed to get cmd for scsi%d\n",
		       instance->host->host_no);
		return -ENOMEM;
	}

	dcmd = &cmd->frame->dcmd;

	if (!instance->vf_affiliation) {
		dev_warn(&instance->pdev->dev, "SR-IOV: Couldn't get LD/VF "
		       "affiliation for scsi%d\n", instance->host->host_no);
		megasas_return_cmd(instance, cmd);
		return -ENOMEM;
	}

	if (initial)
		memset(instance->vf_affiliation, 0, (MAX_LOGICAL_DRIVES + 1) *
		       sizeof(struct MR_LD_VF_AFFILIATION));
	else {
		new_affiliation =
			dma_zalloc_coherent(&instance->pdev->dev,
					      (MAX_LOGICAL_DRIVES + 1) *
					      sizeof(struct MR_LD_VF_AFFILIATION),
					      &new_affiliation_h, GFP_KERNEL);
		if (!new_affiliation) {
			dev_printk(KERN_DEBUG, &instance->pdev->dev, "SR-IOV: Couldn't allocate "
			       "memory for new affiliation for scsi%d\n",
			       instance->host->host_no);
			megasas_return_cmd(instance, cmd);
			return -ENOMEM;
		}
	}

	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);

	dcmd->cmd = MFI_CMD_DCMD;
	dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
	dcmd->sge_count = 1;
	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_BOTH);
	dcmd->timeout = 0;
	dcmd->pad_0 = 0;
	dcmd->data_xfer_len = cpu_to_le32((MAX_LOGICAL_DRIVES + 1) *
		sizeof(struct MR_LD_VF_AFFILIATION));
	dcmd->opcode = cpu_to_le32(MR_DCMD_LD_VF_MAP_GET_ALL_LDS);

	if (initial)
		dcmd->sgl.sge32[0].phys_addr =
			cpu_to_le32(instance->vf_affiliation_h);
	else
		dcmd->sgl.sge32[0].phys_addr =
			cpu_to_le32(new_affiliation_h);

	dcmd->sgl.sge32[0].length = cpu_to_le32((MAX_LOGICAL_DRIVES + 1) *
		sizeof(struct MR_LD_VF_AFFILIATION));

	dev_warn(&instance->pdev->dev, "SR-IOV: Getting LD/VF affiliation for "
	       "scsi%d\n", instance->host->host_no);

	if (megasas_issue_blocked_cmd(instance, cmd, 0) != DCMD_SUCCESS) {
		dev_warn(&instance->pdev->dev, "SR-IOV: LD/VF affiliation DCMD"
		       " failed with status 0x%x for scsi%d\n",
		       dcmd->cmd_status, instance->host->host_no);
		retval = 1; /* Do a scan if we couldn't get affiliation */
		goto out;
	}

	if (!initial) {
		if (!new_affiliation->ldCount) {
			dev_warn(&instance->pdev->dev, "SR-IOV: Got new LD/VF "
			       "affiliation for passive path for scsi%d\n",
			       instance->host->host_no);
			retval = 1;
			goto out;
		}
		newmap = new_affiliation->map;
		savedmap = instance->vf_affiliation->map;
		thisVf = new_affiliation->thisVf;
		for (i = 0 ; i < new_affiliation->ldCount; i++) {
			found = 0;
			for (j = 0; j < instance->vf_affiliation->ldCount;
			     j++) {
				if (newmap->ref.targetId ==
				    savedmap->ref.targetId) {
					found = 1;
					if (newmap->policy[thisVf] !=
					    savedmap->policy[thisVf]) {
						doscan = 1;
						goto out;
					}
				}
				savedmap = (struct MR_LD_VF_MAP *)
					((unsigned char *)savedmap +
					 savedmap->size);
			}
			if (!found && newmap->policy[thisVf] !=
			    MR_LD_ACCESS_HIDDEN) {
				doscan = 1;
				goto out;
			}
			newmap = (struct MR_LD_VF_MAP *)
				((unsigned char *)newmap + newmap->size);
		}

		newmap = new_affiliation->map;
		savedmap = instance->vf_affiliation->map;

		for (i = 0 ; i < instance->vf_affiliation->ldCount; i++) {
			found = 0;
			for (j = 0 ; j < new_affiliation->ldCount; j++) {
				if (savedmap->ref.targetId ==
				    newmap->ref.targetId) {
					found = 1;
					if (savedmap->policy[thisVf] !=
					    newmap->policy[thisVf]) {
						doscan = 1;
						goto out;
					}
				}
				newmap = (struct MR_LD_VF_MAP *)
					((unsigned char *)newmap +
					 newmap->size);
			}
			if (!found && savedmap->policy[thisVf] !=
			    MR_LD_ACCESS_HIDDEN) {
				doscan = 1;
				goto out;
			}
			savedmap = (struct MR_LD_VF_MAP *)
				((unsigned char *)savedmap +
				 savedmap->size);
		}
	}
out:
	if (doscan) {
		dev_warn(&instance->pdev->dev, "SR-IOV: Got new LD/VF "
		       "affiliation for scsi%d\n", instance->host->host_no);
		memcpy(instance->vf_affiliation, new_affiliation,
		       new_affiliation->size);
		retval = 1;
	}

	if (new_affiliation)
		dma_free_coherent(&instance->pdev->dev,
				    (MAX_LOGICAL_DRIVES + 1) *
				    sizeof(struct MR_LD_VF_AFFILIATION),
				    new_affiliation, new_affiliation_h);
	megasas_return_cmd(instance, cmd);

	return retval;
}


megasas_check_reset_skinny(struct megasas_instance *instance,
				struct megasas_register_set __iomem *regs)
{
	if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL)
		return 1;

	return 0;
}


megasas_fw_crash_buffer_show(struct device *cdev,
	struct device_attribute *attr, char *buf)
{
	struct Scsi_Host *shost = class_to_shost(cdev);
	struct megasas_instance *instance =
		(struct megasas_instance *) shost->hostdata;
	u32 size;
	unsigned long buff_addr;
	unsigned long dmachunk = CRASH_DMA_BUF_SIZE;
	unsigned long src_addr;
	unsigned long flags;
	u32 buff_offset;

	spin_lock_irqsave(&instance->crashdump_lock, flags);
	buff_offset = instance->fw_crash_buffer_offset;
	if (!instance->crash_dump_buf &&
		!((instance->fw_crash_state == AVAILABLE) ||
		(instance->fw_crash_state == COPYING))) {
		dev_err(&instance->pdev->dev,
			"Firmware crash dump is not available\n");
		spin_unlock_irqrestore(&instance->crashdump_lock, flags);
		return -EINVAL;
	}

	buff_addr = (unsigned long) buf;

	if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) {
		dev_err(&instance->pdev->dev,
			"Firmware crash dump offset is out of range\n");
		spin_unlock_irqrestore(&instance->crashdump_lock, flags);
		return 0;
	}

	size = (instance->fw_crash_buffer_size * dmachunk) - buff_offset;
	size = (size >= PAGE_SIZE) ? (PAGE_SIZE - 1) : size;

	src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] +
		(buff_offset % dmachunk);
	memcpy(buf, (void *)src_addr, size);
	spin_unlock_irqrestore(&instance->crashdump_lock, flags);

	return size;
}


megasas_disable_intr_xscale(struct megasas_instance *instance)
{
	struct megasas_register_set __iomem *regs;
	u32 mask = 0x1f;

	regs = instance->reg_set;
	writel(mask, &regs->outbound_intr_mask);
	/* Dummy readl to force pci flush */
	readl(&regs->outbound_intr_mask);
}


int megasas_get_device_list(struct megasas_instance *instance)
{
	memset(instance->pd_list, 0,
	       (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
	memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);

	if (instance->enable_fw_dev_list) {
		if (megasas_host_device_list_query(instance, true))
			return FAILED;
	} else {
		if (megasas_get_pd_list(instance) < 0) {
			dev_err(&instance->pdev->dev, "failed to get PD list\n");
			return FAILED;
		}

		if (megasas_ld_list_query(instance,
					  MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) {
			dev_err(&instance->pdev->dev, "failed to get LD list\n");
			return FAILED;
		}
	}

	return SUCCESS;
}


megasas_disable_intr_skinny(struct megasas_instance *instance)
{
	struct megasas_register_set __iomem *regs;
	u32 mask = 0xFFFFFFFF;

	regs = instance->reg_set;
	writel(mask, &regs->outbound_intr_mask);
	/* Dummy readl to force pci flush */
	readl(&regs->outbound_intr_mask);
}


static int megasas_init_fw(struct megasas_instance *instance)
{
	u32 max_sectors_1;
	u32 max_sectors_2, tmp_sectors, msix_enable;
	u32 scratch_pad_1, scratch_pad_2, scratch_pad_3, status_reg;
	resource_size_t base_addr;
	struct megasas_ctrl_info *ctrl_info = NULL;
	unsigned long bar_list;
	int i, j, loop, fw_msix_count = 0;
	struct IOV_111 *iovPtr;
	struct fusion_context *fusion;
	bool do_adp_reset = true;

	fusion = instance->ctrl_context;

	/* Find first memory bar */
	bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
	instance->bar = find_first_bit(&bar_list, BITS_PER_LONG);
	if (pci_request_selected_regions(instance->pdev, 1<<instance->bar,
					 "megasas: LSI")) {
		dev_printk(KERN_DEBUG, &instance->pdev->dev, "IO memory region busy!\n");
		return -EBUSY;
	}

	base_addr = pci_resource_start(instance->pdev, instance->bar);
	instance->reg_set = ioremap_nocache(base_addr, 8192);

	if (!instance->reg_set) {
		dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to map IO mem\n");
		goto fail_ioremap;
	}

	if (instance->adapter_type != MFI_SERIES)
		instance->instancet = &megasas_instance_template_fusion;
	else {
		switch (instance->pdev->device) {
		case PCI_DEVICE_ID_LSI_SAS1078R:
		case PCI_DEVICE_ID_LSI_SAS1078DE:
			instance->instancet = &megasas_instance_template_ppc;
			break;
		case PCI_DEVICE_ID_LSI_SAS1078GEN2:
		case PCI_DEVICE_ID_LSI_SAS0079GEN2:
			instance->instancet = &megasas_instance_template_gen2;
			break;
		case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
		case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
			instance->instancet = &megasas_instance_template_skinny;
			break;
		case PCI_DEVICE_ID_LSI_SAS1064R:
		case PCI_DEVICE_ID_DELL_PERC5:
		default:
			instance->instancet = &megasas_instance_template_xscale;
			instance->pd_list_not_supported = 1;
			break;
		}
	}

	if (megasas_transition_to_ready(instance, 0)) {
		if (instance->adapter_type >= INVADER_SERIES) {
			status_reg = instance->instancet->read_fw_status_reg(
					instance);
			do_adp_reset = status_reg & MFI_RESET_ADAPTER;
		}

		if (do_adp_reset) {
			atomic_set(&instance->fw_reset_no_pci_access, 1);
			instance->instancet->adp_reset
				(instance, instance->reg_set);
			atomic_set(&instance->fw_reset_no_pci_access, 0);
			dev_info(&instance->pdev->dev,
				 "FW restarted successfully from %s!\n",
				 __func__);

			/*waiting for about 30 second before retry*/
			ssleep(30);

			if (megasas_transition_to_ready(instance, 0))
				goto fail_ready_state;
		} else {
			goto fail_ready_state;
		}
	}

	megasas_init_ctrl_params(instance);

	if (megasas_set_dma_mask(instance))
		goto fail_ready_state;

	if (megasas_alloc_ctrl_mem(instance))
		goto fail_alloc_dma_buf;

	if (megasas_alloc_ctrl_dma_buffers(instance))
		goto fail_alloc_dma_buf;

	fusion = instance->ctrl_context;

	if (instance->adapter_type >= VENTURA_SERIES) {
		scratch_pad_2 =
			megasas_readl(instance,
				      &instance->reg_set->outbound_scratch_pad_2);
		instance->max_raid_mapsize = ((scratch_pad_2 >>
			MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) &
			MR_MAX_RAID_MAP_SIZE_MASK);
	}

	/* Check if MSI-X is supported while in ready state */
	msix_enable = (instance->instancet->read_fw_status_reg(instance) &
		       0x4000000) >> 0x1a;
	if (msix_enable && !msix_disable) {
		int irq_flags = PCI_IRQ_MSIX;

		scratch_pad_1 = megasas_readl
			(instance, &instance->reg_set->outbound_scratch_pad_1);
		/* Check max MSI-X vectors */
		if (fusion) {
			if (instance->adapter_type == THUNDERBOLT_SERIES) {
				/* Thunderbolt Series*/
				instance->msix_vectors = (scratch_pad_1
					& MR_MAX_REPLY_QUEUES_OFFSET) + 1;
				fw_msix_count = instance->msix_vectors;
			} else {
				instance->msix_vectors = ((scratch_pad_1
					& MR_MAX_REPLY_QUEUES_EXT_OFFSET)
					>> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;

				/*
				 * For Invader series, > 8 MSI-x vectors
				 * supported by FW/HW implies combined
				 * reply queue mode is enabled.
				 * For Ventura series, > 16 MSI-x vectors
				 * supported by FW/HW implies combined
				 * reply queue mode is enabled.
				 */
				switch (instance->adapter_type) {
				case INVADER_SERIES:
					if (instance->msix_vectors > 8)
						instance->msix_combined = true;
					break;
				case AERO_SERIES:
				case VENTURA_SERIES:
					if (instance->msix_vectors > 16)
						instance->msix_combined = true;
					break;
				}

				if (rdpq_enable)
					instance->is_rdpq = (scratch_pad_1 & MR_RDPQ_MODE_OFFSET) ?
								1 : 0;
				fw_msix_count = instance->msix_vectors;
				/* Save 1-15 reply post index address to local memory
				 * Index 0 is already saved from reg offset
				 * MPI2_REPLY_POST_HOST_INDEX_OFFSET
				 */
				for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
					instance->reply_post_host_index_addr[loop] =
						(u32 __iomem *)
						((u8 __iomem *)instance->reg_set +
						MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
						+ (loop * 0x10));
				}
			}
			if (msix_vectors)
				instance->msix_vectors = min(msix_vectors,
					instance->msix_vectors);
		} else /* MFI adapters */
			instance->msix_vectors = 1;
		/* Don't bother allocating more MSI-X vectors than cpus */
		instance->msix_vectors = min(instance->msix_vectors,
					     (unsigned int)num_online_cpus());
		if (smp_affinity_enable)
			irq_flags |= PCI_IRQ_AFFINITY;
		i = pci_alloc_irq_vectors(instance->pdev, 1,
					  instance->msix_vectors, irq_flags);
		if (i > 0)
			instance->msix_vectors = i;
		else
			instance->msix_vectors = 0;
	}
	/*
	 * MSI-X host index 0 is common for all adapter.
	 * It is used for all MPT based Adapters.
	 */
	if (instance->msix_combined) {
		instance->reply_post_host_index_addr[0] =
				(u32 *)((u8 *)instance->reg_set +
				MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET);
	} else {
		instance->reply_post_host_index_addr[0] =
			(u32 *)((u8 *)instance->reg_set +
			MPI2_REPLY_POST_HOST_INDEX_OFFSET);
	}

	if (!instance->msix_vectors) {
		i = pci_alloc_irq_vectors(instance->pdev, 1, 1, PCI_IRQ_LEGACY);
		if (i < 0)
			goto fail_init_adapter;
	}

	megasas_setup_reply_map(instance);

	dev_info(&instance->pdev->dev,
		"firmware supports msix\t: (%d)", fw_msix_count);
	dev_info(&instance->pdev->dev,
		"current msix/online cpus\t: (%d/%d)\n",
		instance->msix_vectors, (unsigned int)num_online_cpus());
	dev_info(&instance->pdev->dev,
		"RDPQ mode\t: (%s)\n", instance->is_rdpq ? "enabled" : "disabled");

	tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
		(unsigned long)instance);

	/*
	 * Below are default value for legacy Firmware.
	 * non-fusion based controllers
	 */
	instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
	instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
	/* Get operational params, sge flags, send init cmd to controller */
	if (instance->instancet->init_adapter(instance))
		goto fail_init_adapter;

	if (instance->adapter_type >= VENTURA_SERIES) {
		scratch_pad_3 =
			megasas_readl(instance,
				      &instance->reg_set->outbound_scratch_pad_3);
		if ((scratch_pad_3 & MR_NVME_PAGE_SIZE_MASK) >=
			MR_DEFAULT_NVME_PAGE_SHIFT)
			instance->nvme_page_size =
				(1 << (scratch_pad_3 & MR_NVME_PAGE_SIZE_MASK));

		dev_info(&instance->pdev->dev,
			 "NVME page size\t: (%d)\n", instance->nvme_page_size);
	}

	if (instance->msix_vectors ?
		megasas_setup_irqs_msix(instance, 1) :
		megasas_setup_irqs_ioapic(instance))
		goto fail_init_adapter;

	instance->instancet->enable_intr(instance);

	dev_info(&instance->pdev->dev, "INIT adapter done\n");

	megasas_setup_jbod_map(instance);

	if (megasas_get_device_list(instance) != SUCCESS) {
		dev_err(&instance->pdev->dev,
			"%s: megasas_get_device_list failed\n",
			__func__);
		goto fail_get_ld_pd_list;
	}

	/* stream detection initialization */
	if (instance->adapter_type >= VENTURA_SERIES) {
		fusion->stream_detect_by_ld =
			kcalloc(MAX_LOGICAL_DRIVES_EXT,
				sizeof(struct LD_STREAM_DETECT *),
				GFP_KERNEL);
		if (!fusion->stream_detect_by_ld) {
			dev_err(&instance->pdev->dev,
				"unable to allocate stream detection for pool of LDs\n");
			goto fail_get_ld_pd_list;
		}
		for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) {
			fusion->stream_detect_by_ld[i] =
				kzalloc(sizeof(struct LD_STREAM_DETECT),
				GFP_KERNEL);
			if (!fusion->stream_detect_by_ld[i]) {
				dev_err(&instance->pdev->dev,
					"unable to allocate stream detect by LD\n ");
				for (j = 0; j < i; ++j)
					kfree(fusion->stream_detect_by_ld[j]);
				kfree(fusion->stream_detect_by_ld);
				fusion->stream_detect_by_ld = NULL;
				goto fail_get_ld_pd_list;
			}
			fusion->stream_detect_by_ld[i]->mru_bit_map
				= MR_STREAM_BITMAP;
		}
	}

	/*
	 * Compute the max allowed sectors per IO: The controller info has two
	 * limits on max sectors. Driver should use the minimum of these two.
	 *
	 * 1 << stripe_sz_ops.min = max sectors per strip
	 *
	 * Note that older firmwares ( < FW ver 30) didn't report information
	 * to calculate max_sectors_1. So the number ended up as zero always.
	 */
	tmp_sectors = 0;
	ctrl_info = instance->ctrl_info_buf;

	max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
		le16_to_cpu(ctrl_info->max_strips_per_io);
	max_sectors_2 = le32_to_cpu(ctrl_info->max_request_size);

	tmp_sectors = min_t(u32, max_sectors_1, max_sectors_2);

	instance->peerIsPresent = ctrl_info->cluster.peerIsPresent;
	instance->passive = ctrl_info->cluster.passive;
	memcpy(instance->clusterId, ctrl_info->clusterId, sizeof(instance->clusterId));
	instance->UnevenSpanSupport =
		ctrl_info->adapterOperations2.supportUnevenSpans;
	if (instance->UnevenSpanSupport) {
		struct fusion_context *fusion = instance->ctrl_context;
		if (MR_ValidateMapInfo(instance, instance->map_id))
			fusion->fast_path_io = 1;
		else
			fusion->fast_path_io = 0;

	}
	if (ctrl_info->host_interface.SRIOV) {
		instance->requestorId = ctrl_info->iov.requestorId;
		if (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA) {
			if (!ctrl_info->adapterOperations2.activePassive)
			    instance->PlasmaFW111 = 1;

			dev_info(&instance->pdev->dev, "SR-IOV: firmware type: %s\n",
			    instance->PlasmaFW111 ? "1.11" : "new");

			if (instance->PlasmaFW111) {
			    iovPtr = (struct IOV_111 *)
				((unsigned char *)ctrl_info + IOV_111_OFFSET);
			    instance->requestorId = iovPtr->requestorId;
			}
		}
		dev_info(&instance->pdev->dev, "SRIOV: VF requestorId %d\n",
			instance->requestorId);
	}

	instance->crash_dump_fw_support =
		ctrl_info->adapterOperations3.supportCrashDump;
	instance->crash_dump_drv_support =
		(instance->crash_dump_fw_support &&
		instance->crash_dump_buf);
	if (instance->crash_dump_drv_support)
		megasas_set_crash_dump_params(instance,
			MR_CRASH_BUF_TURN_OFF);

	else {
		if (instance->crash_dump_buf)
			dma_free_coherent(&instance->pdev->dev,
				CRASH_DMA_BUF_SIZE,
				instance->crash_dump_buf,
				instance->crash_dump_h);
		instance->crash_dump_buf = NULL;
	}

	if (instance->snapdump_wait_time) {
		megasas_get_snapdump_properties(instance);
		dev_info(&instance->pdev->dev, "Snap dump wait time\t: %d\n",
			 instance->snapdump_wait_time);
	}

	dev_info(&instance->pdev->dev,
		"pci id\t\t: (0x%04x)/(0x%04x)/(0x%04x)/(0x%04x)\n",
		le16_to_cpu(ctrl_info->pci.vendor_id),
		le16_to_cpu(ctrl_info->pci.device_id),
		le16_to_cpu(ctrl_info->pci.sub_vendor_id),
		le16_to_cpu(ctrl_info->pci.sub_device_id));
	dev_info(&instance->pdev->dev, "unevenspan support	: %s\n",
		instance->UnevenSpanSupport ? "yes" : "no");
	dev_info(&instance->pdev->dev, "firmware crash dump	: %s\n",
		instance->crash_dump_drv_support ? "yes" : "no");
	dev_info(&instance->pdev->dev, "jbod sync map		: %s\n",
		instance->use_seqnum_jbod_fp ? "yes" : "no");

	instance->max_sectors_per_req = instance->max_num_sge *
						SGE_BUFFER_SIZE / 512;
	if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
		instance->max_sectors_per_req = tmp_sectors;

	/* Check for valid throttlequeuedepth module parameter */
	if (throttlequeuedepth &&
			throttlequeuedepth <= instance->max_scsi_cmds)
		instance->throttlequeuedepth = throttlequeuedepth;
	else
		instance->throttlequeuedepth =
				MEGASAS_THROTTLE_QUEUE_DEPTH;

	if ((resetwaittime < 1) ||
	    (resetwaittime > MEGASAS_RESET_WAIT_TIME))
		resetwaittime = MEGASAS_RESET_WAIT_TIME;

	if ((scmd_timeout < 10) || (scmd_timeout > MEGASAS_DEFAULT_CMD_TIMEOUT))
		scmd_timeout = MEGASAS_DEFAULT_CMD_TIMEOUT;

	/* Launch SR-IOV heartbeat timer */
	if (instance->requestorId) {
		if (!megasas_sriov_start_heartbeat(instance, 1)) {
			megasas_start_timer(instance);
		} else {
			instance->skip_heartbeat_timer_del = 1;
			goto fail_get_ld_pd_list;
		}
	}

	/*
	 * Create and start watchdog thread which will monitor
	 * controller state every 1 sec and trigger OCR when
	 * it enters fault state
	 */
	if (instance->adapter_type != MFI_SERIES)
		if (megasas_fusion_start_watchdog(instance) != SUCCESS)
			goto fail_start_watchdog;

	return 0;

fail_start_watchdog:
	if (instance->requestorId && !instance->skip_heartbeat_timer_del)
		del_timer_sync(&instance->sriov_heartbeat_timer);
fail_get_ld_pd_list:
	instance->instancet->disable_intr(instance);
	megasas_destroy_irqs(instance);
fail_init_adapter:
	if (instance->msix_vectors)
		pci_free_irq_vectors(instance->pdev);
	instance->msix_vectors = 0;
fail_alloc_dma_buf:
	megasas_free_ctrl_dma_buffers(instance);
	megasas_free_ctrl_mem(instance);
fail_ready_state:
	iounmap(instance->reg_set);

fail_ioremap:
	pci_release_selected_regions(instance->pdev, 1<<instance->bar);

	dev_err(&instance->pdev->dev, "Failed from %s %d\n",
		__func__, __LINE__);
	return -EINVAL;
}


megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
{
	int ret = 0, ld_index = 0, ids = 0;
	struct megasas_cmd *cmd;
	struct megasas_dcmd_frame *dcmd;
	struct MR_LD_TARGETID_LIST *ci;
	dma_addr_t ci_h = 0;
	u32 tgtid_count;

	ci = instance->ld_targetid_list_buf;
	ci_h = instance->ld_targetid_list_buf_h;

	cmd = megasas_get_cmd(instance);

	if (!cmd) {
		dev_warn(&instance->pdev->dev,
		         "megasas_ld_list_query: Failed to get cmd\n");
		return -ENOMEM;
	}

	dcmd = &cmd->frame->dcmd;

	memset(ci, 0, sizeof(*ci));
	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);

	dcmd->mbox.b[0] = query_type;
	if (instance->supportmax256vd)
		dcmd->mbox.b[2] = 1;

	dcmd->cmd = MFI_CMD_DCMD;
	dcmd->cmd_status = MFI_STAT_INVALID_STATUS;
	dcmd->sge_count = 1;
	dcmd->flags = MFI_FRAME_DIR_READ;
	dcmd->timeout = 0;
	dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_TARGETID_LIST));
	dcmd->opcode = cpu_to_le32(MR_DCMD_LD_LIST_QUERY);
	dcmd->pad_0  = 0;

	megasas_set_dma_settings(instance, dcmd, ci_h,
				 sizeof(struct MR_LD_TARGETID_LIST));

	if ((instance->adapter_type != MFI_SERIES) &&
	    !instance->mask_interrupts)
		ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS);
	else
		ret = megasas_issue_polled(instance, cmd);

	switch (ret) {
	case DCMD_FAILED:
		dev_info(&instance->pdev->dev,
			"DCMD not supported by firmware - %s %d\n",
				__func__, __LINE__);
		ret = megasas_get_ld_list(instance);
		break;
	case DCMD_TIMEOUT:
		switch (dcmd_timeout_ocr_possible(instance)) {
		case INITIATE_OCR:
			cmd->flags |= DRV_DCMD_SKIP_REFIRE;
			/*
			 * DCMD failed from AEN path.
			 * AEN path already hold reset_mutex to avoid PCI access
			 * while OCR is in progress.
			 */
			mutex_unlock(&instance->reset_mutex);
			megasas_reset_fusion(instance->host,
						MFI_IO_TIMEOUT_OCR);
			mutex_lock(&instance->reset_mutex);
			break;
		case KILL_ADAPTER:
			megaraid_sas_kill_hba(instance);
			break;
		case IGNORE_TIMEOUT:
			dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d\n",
				__func__, __LINE__);
			break;
		}

		break;
	case DCMD_SUCCESS:
		tgtid_count = le32_to_cpu(ci->count);

		if ((tgtid_count > (instance->fw_supported_vd_count)))
			break;

		memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
		for (ld_index = 0; ld_index < tgtid_count; ld_index++) {
			ids = ci->targetId[ld_index];
			instance->ld_ids[ids] = ci->targetId[ld_index];
		}

		break;
	}

	if (ret != DCMD_TIMEOUT)
		megasas_return_cmd(instance, cmd);

	return ret;
}