11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* $Id: message.c,v 1.5.8.2 2001/09/23 22:24:59 kai Exp $
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * functions for sending and receiving control messages
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1996  SpellCaster Telecommunications Inc.
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software may be used and distributed according to the terms
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the GNU General Public License, incorporated herein by reference.
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For more information, please contact gpl-info@spellcast.com or write:
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     SpellCaster Telecommunications Inc.
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     5621 Finch Avenue East, Unit #3
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Scarborough, Ontario  Canada
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     M1B 2T9
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     +1 (416) 297-8565
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     +1 (416) 297-6433 Facsimile
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
19e8edc6e03a5c8562dc70a6d969f732bdb355a7e7Alexey Dobriyan#include <linux/sched.h>
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "includes.h"
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hardware.h"
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "message.h"
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "card.h"
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * receive a message from the board
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
28475be4d85a274d0961593db41cf85689db1d583cJoe Perchesint receivemessage(int card, RspMessage *rspmsg)
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DualPortMemory *dpm;
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_VALID_CARD(card)) {
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pr_debug("Invalid param: %d is not a valid card id\n", card);
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
37475be4d85a274d0961593db41cf85689db1d583cJoe Perches
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pr_debug("%s: Entered receivemessage\n",
39475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 sc_adapter[card]->devicename);
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * See if there are messages waiting
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (inb(sc_adapter[card]->ioport[FIFO_STATUS]) & RF_HAS_DATA) {
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Map in the DPM to the base page and copy the message
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		spin_lock_irqsave(&sc_adapter[card]->lock, flags);
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		outb((sc_adapter[card]->shmem_magic >> 14) | 0x80,
50475be4d85a274d0961593db41cf85689db1d583cJoe Perches		     sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dpm = (DualPortMemory *) sc_adapter[card]->rambase;
52475be4d85a274d0961593db41cf85689db1d583cJoe Perches		memcpy_fromio(rspmsg, &(dpm->rsp_queue[dpm->rsp_tail]),
53475be4d85a274d0961593db41cf85689db1d583cJoe Perches			      MSG_LEN);
54475be4d85a274d0961593db41cf85689db1d583cJoe Perches		dpm->rsp_tail = (dpm->rsp_tail + 1) % MAX_MESSAGES;
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		inb(sc_adapter[card]->ioport[FIFO_READ]);
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Tell the board that the message is received
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pr_debug("%s: Received Message seq:%d pid:%d time:%d cmd:%d "
61475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 "cnt:%d (type,class,code):(%d,%d,%d) "
62475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 "link:%d stat:0x%x\n",
63475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 sc_adapter[card]->devicename,
64475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 rspmsg->sequence_no,
65475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 rspmsg->process_id,
66475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 rspmsg->time_stamp,
67475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 rspmsg->cmd_sequence_no,
68475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 rspmsg->msg_byte_cnt,
69475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 rspmsg->type,
70475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 rspmsg->class,
71475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 rspmsg->code,
72475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 rspmsg->phy_link_no,
73475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 rspmsg->rsp_status);
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return -ENOMSG;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
79475be4d85a274d0961593db41cf85689db1d583cJoe Perches
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * send a message to the board
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint sendmessage(int card,
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		unsigned int procid,
85475be4d85a274d0961593db41cf85689db1d583cJoe Perches		unsigned int type,
86475be4d85a274d0961593db41cf85689db1d583cJoe Perches		unsigned int class,
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		unsigned int code,
88475be4d85a274d0961593db41cf85689db1d583cJoe Perches		unsigned int link,
89475be4d85a274d0961593db41cf85689db1d583cJoe Perches		unsigned int data_len,
90475be4d85a274d0961593db41cf85689db1d583cJoe Perches		unsigned int *data)
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DualPortMemory *dpm;
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ReqMessage sndmsg;
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_VALID_CARD(card)) {
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pr_debug("Invalid param: %d is not a valid card id\n", card);
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Make sure we only send CEPID messages when the engine is up
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * and CMPID messages when it is down
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
105475be4d85a274d0961593db41cf85689db1d583cJoe Perches	if (sc_adapter[card]->EngineUp && procid == CMPID) {
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pr_debug("%s: Attempt to send CM message with engine up\n",
107475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 sc_adapter[card]->devicename);
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ESRCH;
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
111475be4d85a274d0961593db41cf85689db1d583cJoe Perches	if (!sc_adapter[card]->EngineUp && procid == CEPID) {
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pr_debug("%s: Attempt to send CE message with engine down\n",
113475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 sc_adapter[card]->devicename);
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ESRCH;
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&sndmsg, 0, MSG_LEN);
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sndmsg.msg_byte_cnt = 4;
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sndmsg.type = type;
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sndmsg.class = class;
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sndmsg.code = code;
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sndmsg.phy_link_no = link;
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (data_len > 0) {
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (data_len > MSG_DATA_LEN)
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			data_len = MSG_DATA_LEN;
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		memcpy(&(sndmsg.msg_data), data, data_len);
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sndmsg.msg_byte_cnt = data_len + 8;
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sndmsg.process_id = procid;
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sndmsg.sequence_no = sc_adapter[card]->seq_no++ % 256;
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * wait for an empty slot in the queue
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (!(inb(sc_adapter[card]->ioport[FIFO_STATUS]) & WF_NOT_FULL))
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		udelay(1);
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Disable interrupts and map in shared memory
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave(&sc_adapter[card]->lock, flags);
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	outb((sc_adapter[card]->shmem_magic >> 14) | 0x80,
145475be4d85a274d0961593db41cf85689db1d583cJoe Perches	     sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dpm = (DualPortMemory *) sc_adapter[card]->rambase;	/* Fix me */
147475be4d85a274d0961593db41cf85689db1d583cJoe Perches	memcpy_toio(&(dpm->req_queue[dpm->req_head]), &sndmsg, MSG_LEN);
148475be4d85a274d0961593db41cf85689db1d583cJoe Perches	dpm->req_head = (dpm->req_head + 1) % MAX_MESSAGES;
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	outb(sndmsg.sequence_no, sc_adapter[card]->ioport[FIFO_WRITE]);
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
151475be4d85a274d0961593db41cf85689db1d583cJoe Perches
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pr_debug("%s: Sent Message seq:%d pid:%d time:%d "
153475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 "cnt:%d (type,class,code):(%d,%d,%d) "
154475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 "link:%d\n ",
155475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 sc_adapter[card]->devicename,
156475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 sndmsg.sequence_no,
157475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 sndmsg.process_id,
158475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 sndmsg.time_stamp,
159475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 sndmsg.msg_byte_cnt,
160475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 sndmsg.type,
161475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 sndmsg.class,
162475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 sndmsg.code,
163475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 sndmsg.phy_link_no);
164475be4d85a274d0961593db41cf85689db1d583cJoe Perches
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint send_and_receive(int card,
169475be4d85a274d0961593db41cf85689db1d583cJoe Perches		     unsigned int procid,
170475be4d85a274d0961593db41cf85689db1d583cJoe Perches		     unsigned char type,
171475be4d85a274d0961593db41cf85689db1d583cJoe Perches		     unsigned char class,
172475be4d85a274d0961593db41cf85689db1d583cJoe Perches		     unsigned char code,
173475be4d85a274d0961593db41cf85689db1d583cJoe Perches		     unsigned char link,
174475be4d85a274d0961593db41cf85689db1d583cJoe Perches		     unsigned char data_len,
175475be4d85a274d0961593db41cf85689db1d583cJoe Perches		     unsigned char *data,
176475be4d85a274d0961593db41cf85689db1d583cJoe Perches		     RspMessage *mesgdata,
177475be4d85a274d0961593db41cf85689db1d583cJoe Perches		     int timeout)
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int retval;
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int tries;
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_VALID_CARD(card)) {
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pr_debug("Invalid param: %d is not a valid card id\n", card);
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sc_adapter[card]->want_async_messages = 1;
188475be4d85a274d0961593db41cf85689db1d583cJoe Perches	retval = sendmessage(card, procid, type, class, code, link,
189475be4d85a274d0961593db41cf85689db1d583cJoe Perches			     data_len, (unsigned int *) data);
190475be4d85a274d0961593db41cf85689db1d583cJoe Perches
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (retval) {
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pr_debug("%s: SendMessage failed in SAR\n",
193475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 sc_adapter[card]->devicename);
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sc_adapter[card]->want_async_messages = 0;
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EIO;
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tries = 0;
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* wait for the response */
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (tries < timeout) {
20124763c48a3c9cdf0a138038b51a7fca65859cd78Nishanth Aravamudan		schedule_timeout_interruptible(1);
202475be4d85a274d0961593db41cf85689db1d583cJoe Perches
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pr_debug("SAR waiting..\n");
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * See if we got our message back
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((sc_adapter[card]->async_msg.type == type) &&
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    (sc_adapter[card]->async_msg.class == class) &&
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    (sc_adapter[card]->async_msg.code == code) &&
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    (sc_adapter[card]->async_msg.phy_link_no == link)) {
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/*
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 * Got it!
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 */
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			pr_debug("%s: Got ASYNC message\n",
217475be4d85a274d0961593db41cf85689db1d583cJoe Perches				 sc_adapter[card]->devicename);
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			memcpy(mesgdata, &(sc_adapter[card]->async_msg),
219475be4d85a274d0961593db41cf85689db1d583cJoe Perches			       sizeof(RspMessage));
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sc_adapter[card]->want_async_messages = 0;
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
224475be4d85a274d0961593db41cf85689db1d583cJoe Perches		tries++;
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pr_debug("%s: SAR message timeout\n", sc_adapter[card]->devicename);
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sc_adapter[card]->want_async_messages = 0;
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return -ETIME;
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
231