Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/isdn/sc/message.c
15111 views
1
/* $Id: message.c,v 1.5.8.2 2001/09/23 22:24:59 kai Exp $
2
*
3
* functions for sending and receiving control messages
4
*
5
* Copyright (C) 1996 SpellCaster Telecommunications Inc.
6
*
7
* This software may be used and distributed according to the terms
8
* of the GNU General Public License, incorporated herein by reference.
9
*
10
* For more information, please contact [email protected] or write:
11
*
12
* SpellCaster Telecommunications Inc.
13
* 5621 Finch Avenue East, Unit #3
14
* Scarborough, Ontario Canada
15
* M1B 2T9
16
* +1 (416) 297-8565
17
* +1 (416) 297-6433 Facsimile
18
*/
19
#include <linux/sched.h>
20
#include "includes.h"
21
#include "hardware.h"
22
#include "message.h"
23
#include "card.h"
24
25
/*
26
* receive a message from the board
27
*/
28
int receivemessage(int card, RspMessage *rspmsg)
29
{
30
DualPortMemory *dpm;
31
unsigned long flags;
32
33
if (!IS_VALID_CARD(card)) {
34
pr_debug("Invalid param: %d is not a valid card id\n", card);
35
return -EINVAL;
36
}
37
38
pr_debug("%s: Entered receivemessage\n",
39
sc_adapter[card]->devicename);
40
41
/*
42
* See if there are messages waiting
43
*/
44
if (inb(sc_adapter[card]->ioport[FIFO_STATUS]) & RF_HAS_DATA) {
45
/*
46
* Map in the DPM to the base page and copy the message
47
*/
48
spin_lock_irqsave(&sc_adapter[card]->lock, flags);
49
outb((sc_adapter[card]->shmem_magic >> 14) | 0x80,
50
sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
51
dpm = (DualPortMemory *) sc_adapter[card]->rambase;
52
memcpy_fromio(rspmsg, &(dpm->rsp_queue[dpm->rsp_tail]),
53
MSG_LEN);
54
dpm->rsp_tail = (dpm->rsp_tail+1) % MAX_MESSAGES;
55
inb(sc_adapter[card]->ioport[FIFO_READ]);
56
spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
57
/*
58
* Tell the board that the message is received
59
*/
60
pr_debug("%s: Received Message seq:%d pid:%d time:%d cmd:%d "
61
"cnt:%d (type,class,code):(%d,%d,%d) "
62
"link:%d stat:0x%x\n",
63
sc_adapter[card]->devicename,
64
rspmsg->sequence_no,
65
rspmsg->process_id,
66
rspmsg->time_stamp,
67
rspmsg->cmd_sequence_no,
68
rspmsg->msg_byte_cnt,
69
rspmsg->type,
70
rspmsg->class,
71
rspmsg->code,
72
rspmsg->phy_link_no,
73
rspmsg->rsp_status);
74
75
return 0;
76
}
77
return -ENOMSG;
78
}
79
80
/*
81
* send a message to the board
82
*/
83
int sendmessage(int card,
84
unsigned int procid,
85
unsigned int type,
86
unsigned int class,
87
unsigned int code,
88
unsigned int link,
89
unsigned int data_len,
90
unsigned int *data)
91
{
92
DualPortMemory *dpm;
93
ReqMessage sndmsg;
94
unsigned long flags;
95
96
if (!IS_VALID_CARD(card)) {
97
pr_debug("Invalid param: %d is not a valid card id\n", card);
98
return -EINVAL;
99
}
100
101
/*
102
* Make sure we only send CEPID messages when the engine is up
103
* and CMPID messages when it is down
104
*/
105
if(sc_adapter[card]->EngineUp && procid == CMPID) {
106
pr_debug("%s: Attempt to send CM message with engine up\n",
107
sc_adapter[card]->devicename);
108
return -ESRCH;
109
}
110
111
if(!sc_adapter[card]->EngineUp && procid == CEPID) {
112
pr_debug("%s: Attempt to send CE message with engine down\n",
113
sc_adapter[card]->devicename);
114
return -ESRCH;
115
}
116
117
memset(&sndmsg, 0, MSG_LEN);
118
sndmsg.msg_byte_cnt = 4;
119
sndmsg.type = type;
120
sndmsg.class = class;
121
sndmsg.code = code;
122
sndmsg.phy_link_no = link;
123
124
if (data_len > 0) {
125
if (data_len > MSG_DATA_LEN)
126
data_len = MSG_DATA_LEN;
127
memcpy(&(sndmsg.msg_data), data, data_len);
128
sndmsg.msg_byte_cnt = data_len + 8;
129
}
130
131
sndmsg.process_id = procid;
132
sndmsg.sequence_no = sc_adapter[card]->seq_no++ % 256;
133
134
/*
135
* wait for an empty slot in the queue
136
*/
137
while (!(inb(sc_adapter[card]->ioport[FIFO_STATUS]) & WF_NOT_FULL))
138
udelay(1);
139
140
/*
141
* Disable interrupts and map in shared memory
142
*/
143
spin_lock_irqsave(&sc_adapter[card]->lock, flags);
144
outb((sc_adapter[card]->shmem_magic >> 14) | 0x80,
145
sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
146
dpm = (DualPortMemory *) sc_adapter[card]->rambase; /* Fix me */
147
memcpy_toio(&(dpm->req_queue[dpm->req_head]),&sndmsg,MSG_LEN);
148
dpm->req_head = (dpm->req_head+1) % MAX_MESSAGES;
149
outb(sndmsg.sequence_no, sc_adapter[card]->ioport[FIFO_WRITE]);
150
spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
151
152
pr_debug("%s: Sent Message seq:%d pid:%d time:%d "
153
"cnt:%d (type,class,code):(%d,%d,%d) "
154
"link:%d\n ",
155
sc_adapter[card]->devicename,
156
sndmsg.sequence_no,
157
sndmsg.process_id,
158
sndmsg.time_stamp,
159
sndmsg.msg_byte_cnt,
160
sndmsg.type,
161
sndmsg.class,
162
sndmsg.code,
163
sndmsg.phy_link_no);
164
165
return 0;
166
}
167
168
int send_and_receive(int card,
169
unsigned int procid,
170
unsigned char type,
171
unsigned char class,
172
unsigned char code,
173
unsigned char link,
174
unsigned char data_len,
175
unsigned char *data,
176
RspMessage *mesgdata,
177
int timeout)
178
{
179
int retval;
180
int tries;
181
182
if (!IS_VALID_CARD(card)) {
183
pr_debug("Invalid param: %d is not a valid card id\n", card);
184
return -EINVAL;
185
}
186
187
sc_adapter[card]->want_async_messages = 1;
188
retval = sendmessage(card, procid, type, class, code, link,
189
data_len, (unsigned int *) data);
190
191
if (retval) {
192
pr_debug("%s: SendMessage failed in SAR\n",
193
sc_adapter[card]->devicename);
194
sc_adapter[card]->want_async_messages = 0;
195
return -EIO;
196
}
197
198
tries = 0;
199
/* wait for the response */
200
while (tries < timeout) {
201
schedule_timeout_interruptible(1);
202
203
pr_debug("SAR waiting..\n");
204
205
/*
206
* See if we got our message back
207
*/
208
if ((sc_adapter[card]->async_msg.type == type) &&
209
(sc_adapter[card]->async_msg.class == class) &&
210
(sc_adapter[card]->async_msg.code == code) &&
211
(sc_adapter[card]->async_msg.phy_link_no == link)) {
212
213
/*
214
* Got it!
215
*/
216
pr_debug("%s: Got ASYNC message\n",
217
sc_adapter[card]->devicename);
218
memcpy(mesgdata, &(sc_adapter[card]->async_msg),
219
sizeof(RspMessage));
220
sc_adapter[card]->want_async_messages = 0;
221
return 0;
222
}
223
224
tries++;
225
}
226
227
pr_debug("%s: SAR message timeout\n", sc_adapter[card]->devicename);
228
sc_adapter[card]->want_async_messages = 0;
229
return -ETIME;
230
}
231
232