OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [isdn/] [sc/] [message.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* $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 gpl-info@spellcast.com 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
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.