summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/nfc/nfcmrvl/fw_dnld.c
diff options
context:
space:
mode:
authorYunhong Jiang <yunhong.jiang@gmail.com>2016-06-13 14:20:00 -0700
committerYunhong Jiang <yunhong.jiang@linux.intel.com>2016-07-18 08:06:07 -0700
commitab9c81f473b3feff08f1e51428fbaf6a93d4896a (patch)
tree60b52c9ea8b9c06a8a349957b8c66f3bb18c5cae /kernel/drivers/nfc/nfcmrvl/fw_dnld.c
parentc715b6029fd5b4eaf323f5efde4ec5db5ba0a9b4 (diff)
kvm: lapic: separate start_sw_tscdeadline from start_apic_timer
The function to start the tsc deadline timer virtualization will be used also by the pre_block hook when we use the preemption timer; change it to a separate function. No logic changes. upstream-status: backport Change-Id: Ie2fc19108c3252f8a299b17aba16c14aa8d31ae8 Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Yunhong Jiang <yunhong.jiang@linux.intel.com>
Diffstat (limited to 'kernel/drivers/nfc/nfcmrvl/fw_dnld.c')
0 files changed, 0 insertions, 0 deletions
>170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
/* $Id: message.c,v 1.5.8.2 2001/09/23 22:24:59 kai Exp $
 *
 * functions for sending and receiving control messages
 *
 * Copyright (C) 1996  SpellCaster Telecommunications Inc.
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 * For more information, please contact gpl-info@spellcast.com or write:
 *
 *     SpellCaster Telecommunications Inc.
 *     5621 Finch Avenue East, Unit #3
 *     Scarborough, Ontario  Canada
 *     M1B 2T9
 *     +1 (416) 297-8565
 *     +1 (416) 297-6433 Facsimile
 */
#include <linux/sched.h>
#include "includes.h"
#include "hardware.h"
#include "message.h"
#include "card.h"

/*
 * receive a message from the board
 */
int receivemessage(int card, RspMessage *rspmsg)
{
	DualPortMemory *dpm;
	unsigned long flags;

	if (!IS_VALID_CARD(card)) {
		pr_debug("Invalid param: %d is not a valid card id\n", card);
		return -EINVAL;
	}

	pr_debug("%s: Entered receivemessage\n",
		 sc_adapter[card]->devicename);

	/*
	 * See if there are messages waiting
	 */
	if (inb(sc_adapter[card]->ioport[FIFO_STATUS]) & RF_HAS_DATA) {
		/*
		 * Map in the DPM to the base page and copy the message
		 */
		spin_lock_irqsave(&sc_adapter[card]->lock, flags);
		outb((sc_adapter[card]->shmem_magic >> 14) | 0x80,
		     sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
		dpm = (DualPortMemory *) sc_adapter[card]->rambase;
		memcpy_fromio(rspmsg, &(dpm->rsp_queue[dpm->rsp_tail]),
			      MSG_LEN);
		dpm->rsp_tail = (dpm->rsp_tail + 1) % MAX_MESSAGES;
		inb(sc_adapter[card]->ioport[FIFO_READ]);
		spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
		/*
		 * Tell the board that the message is received
		 */
		pr_debug("%s: Received Message seq:%d pid:%d time:%d cmd:%d "
			 "cnt:%d (type,class,code):(%d,%d,%d) "
			 "link:%d stat:0x%x\n",
			 sc_adapter[card]->devicename,
			 rspmsg->sequence_no,
			 rspmsg->process_id,
			 rspmsg->time_stamp,
			 rspmsg->cmd_sequence_no,
			 rspmsg->msg_byte_cnt,
			 rspmsg->type,
			 rspmsg->class,
			 rspmsg->code,
			 rspmsg->phy_link_no,
			 rspmsg->rsp_status);

		return 0;
	}
	return -ENOMSG;
}

/*
 * send a message to the board
 */
int sendmessage(int card,
		unsigned int procid,
		unsigned int type,
		unsigned int class,
		unsigned int code,
		unsigned int link,
		unsigned int data_len,
		unsigned int *data)
{
	DualPortMemory *dpm;
	ReqMessage sndmsg;
	unsigned long flags;

	if (!IS_VALID_CARD(card)) {
		pr_debug("Invalid param: %d is not a valid card id\n", card);
		return -EINVAL;
	}

	/*
	 * Make sure we only send CEPID messages when the engine is up
	 * and CMPID messages when it is down
	 */
	if (sc_adapter[card]->EngineUp && procid == CMPID) {
		pr_debug("%s: Attempt to send CM message with engine up\n",
			 sc_adapter[card]->devicename);
		return -ESRCH;
	}

	if (!sc_adapter[card]->EngineUp && procid == CEPID) {
		pr_debug("%s: Attempt to send CE message with engine down\n",
			 sc_adapter[card]->devicename);
		return -ESRCH;
	}

	memset(&sndmsg, 0, MSG_LEN);
	sndmsg.msg_byte_cnt = 4;
	sndmsg.type = type;
	sndmsg.class = class;
	sndmsg.code = code;
	sndmsg.phy_link_no = link;

	if (data_len > 0) {
		if (data_len > MSG_DATA_LEN)
			data_len = MSG_DATA_LEN;
		memcpy(&(sndmsg.msg_data), data, data_len);
		sndmsg.msg_byte_cnt = data_len + 8;
	}

	sndmsg.process_id = procid;
	sndmsg.sequence_no = sc_adapter[card]->seq_no++ % 256;

	/*
	 * wait for an empty slot in the queue
	 */
	while (!(inb(sc_adapter[card]->ioport[FIFO_STATUS]) & WF_NOT_FULL))
		udelay(1);

	/*
	 * Disable interrupts and map in shared memory
	 */
	spin_lock_irqsave(&sc_adapter[card]->lock, flags);
	outb((sc_adapter[card]->shmem_magic >> 14) | 0x80,
	     sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
	dpm = (DualPortMemory *) sc_adapter[card]->rambase;	/* Fix me */
	memcpy_toio(&(dpm->req_queue[dpm->req_head]), &sndmsg, MSG_LEN);
	dpm->req_head = (dpm->req_head + 1) % MAX_MESSAGES;
	outb(sndmsg.sequence_no, sc_adapter[card]->ioport[FIFO_WRITE]);
	spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);

	pr_debug("%s: Sent Message seq:%d pid:%d time:%d "
		 "cnt:%d (type,class,code):(%d,%d,%d) "
		 "link:%d\n ",
		 sc_adapter[card]->devicename,
		 sndmsg.sequence_no,
		 sndmsg.process_id,
		 sndmsg.time_stamp,
		 sndmsg.msg_byte_cnt,
		 sndmsg.type,
		 sndmsg.class,
		 sndmsg.code,
		 sndmsg.phy_link_no);

	return 0;
}

int send_and_receive(int card,
		     unsigned int procid,
		     unsigned char type,
		     unsigned char class,
		     unsigned char code,
		     unsigned char link,
		     unsigned char data_len,
		     unsigned char *data,
		     RspMessage *mesgdata,
		     int timeout)
{
	int retval;
	int tries;

	if (!IS_VALID_CARD(card)) {
		pr_debug("Invalid param: %d is not a valid card id\n", card);
		return -EINVAL;
	}

	sc_adapter[card]->want_async_messages = 1;
	retval = sendmessage(card, procid, type, class, code, link,
			     data_len, (unsigned int *) data);

	if (retval) {
		pr_debug("%s: SendMessage failed in SAR\n",
			 sc_adapter[card]->devicename);
		sc_adapter[card]->want_async_messages = 0;
		return -EIO;
	}

	tries = 0;
	/* wait for the response */
	while (tries < timeout) {
		schedule_timeout_interruptible(1);

		pr_debug("SAR waiting..\n");

		/*
		 * See if we got our message back
		 */
		if ((sc_adapter[card]->async_msg.type == type) &&
		    (sc_adapter[card]->async_msg.class == class) &&
		    (sc_adapter[card]->async_msg.code == code) &&
		    (sc_adapter[card]->async_msg.phy_link_no == link)) {

			/*
			 * Got it!
			 */
			pr_debug("%s: Got ASYNC message\n",
				 sc_adapter[card]->devicename);
			memcpy(mesgdata, &(sc_adapter[card]->async_msg),
			       sizeof(RspMessage));
			sc_adapter[card]->want_async_messages = 0;
			return 0;
		}

		tries++;
	}

	pr_debug("%s: SAR message timeout\n", sc_adapter[card]->devicename);
	sc_adapter[card]->want_async_messages = 0;
	return -ETIME;
}