Lynx framebuffers multidomain implementation.
[linux/elbrus.git] / drivers / mcst / mokx / mokx_write_buf.c
blob0e3675981b5d120633e903a641fff87daa098aee
1 #define CLEAR_PD pd->dsf = 0; \
2 pd->int_ac = 0; \
3 pd->stat = 0; \
4 pd->msg = 0;
6 #define WRITE_BUF_DBG 0
7 #define WRITE_BUF_DEBUG_MSG(x...)\
8 if (WRITE_BUF_DBG) DEBUG_MSG(x)
9 #define WR_DBG WRITE_BUF_DEBUG_MSG
10 #define repeate_WRITE 10
12 int write_buf(int link, rdma_ioc_parm_t *parm, unsigned int f_flags)
14 rdma_state_link_t *rdma_link;
15 rdma_pool_buf_t *w_pool_buf;
16 dev_rdma_sem_t *dev_sem;
17 struct stat_rdma *pst;
18 rdma_buf_t *w_buf;
19 rw_state_p pd;
20 size_t size;
21 unsigned long flags;
22 signed long io_timeout = 0;
23 unsigned int sending_msg;
24 int ret_time_dwait = 0;
25 int num;
26 int ret_smsg;
27 int ret = 0;
29 num = parm->acclen;
30 size = parm->reqlen;
31 rdma_link = &rdma_state->rdma_link[link];
32 w_pool_buf = &rdma_link->write_pool;
33 w_buf = &w_pool_buf->buf[num];
34 pd = &rdma_link->rw_states_d[WRITER];
35 pst = &rdma_link->stat_rdma;
36 dev_sem = &pd->dev_rdma_sem;
37 dev_sem->time_broadcast = 0;
38 WR_DBG("%s: link: %d num buf: %d size: 0x%016lx\n", __FUNCTION__, link,
39 num, size);
40 event_write(link, WRITE_1_EVENT, size, dev_sem->num_obmen);
41 raw_spin_lock_irqsave(&dev_sem->lock, flags);
42 pd->int_ac = 0;
44 * Receive's buffer busy
46 if ((!pd->trwd_was) && ( f_flags & O_NONBLOCK )) {
47 raw_spin_unlock_irqrestore(&dev_sem->lock, flags);
48 parm->err_no = RDMA_E_NULL_BUFFER;
49 event_write(link, WRITE_0_EVENT, 0, dev_sem->num_obmen);
50 return -EAGAIN;
52 if (!pd->trwd_was) {
54 * Set timeout
56 if (dev_sem->timeout == 0) {
57 io_timeout = IO_TIMEOUT;
58 } else {
59 io_timeout = dev_sem->timeout * HZ;
62 * Waiting for the release receive buffer.
63 * Wake up by MSG_READY_DMA.
65 pd->int_ac = 1;
66 ret_time_dwait = wait_for_irq_rdma_sem(dev_sem, io_timeout, link);
67 if (dev_sem->irq_count_rdma != 1) {
68 ERROR_MSG("%s: link: %d MSG wait_1 bad irq "
69 "dev_sem->irq_count_rdma: 0x%08x\n",
70 __FUNCTION__, link, dev_sem->irq_count_rdma);
71 dev_sem->irq_count_rdma = 0;
72 if (ev_pr)
73 get_event_rdma(1);
74 } else {
75 dev_sem->irq_count_rdma = 0;
77 if (ret_time_dwait < 0) {
78 CLEAR_PD
79 raw_spin_unlock_irqrestore(&dev_sem->lock, flags);
80 WR_DBG("%s: link: %d ret_time_dwait: %d\n", __FUNCTION__,
81 link, ret_time_dwait);
82 event_write(link, WRITE_BAD1_EVENT,
83 -ret_time_dwait, dev_sem->num_obmen);
84 switch (ret_time_dwait) {
85 case -1:
86 ERROR_MSG("%s: link: %d MSG RDMA_E_WRITE_TIMEOUT num_obmen: 0x%08x\n",
87 __FUNCTION__, link, dev_sem->num_obmen);
88 parm->err_no = RDMA_E_WRITE_TIMEOUT;
89 ret = -ETIME;
90 read_regs_rdma(link);
91 break;
92 case -2:
93 ERROR_MSG("%s: link: %d MSG RDMA_E_SIGNAL num_obmen: 0x%08x\n",
94 __FUNCTION__, link, dev_sem->num_obmen);
95 parm->err_no = RDMA_E_SIGNAL;
96 ret = -EINTR;
97 break;
98 default:
99 ERROR_MSG("%s: link: %d MSG RDMA_E_SPIN num_obmen: 0x%08x\n",
100 __FUNCTION__, link, dev_sem->num_obmen);
101 parm->err_no = RDMA_E_SPIN;
102 ret = -EAGAIN;
104 if (ev_pr)
105 get_event_rdma(1);
106 goto exit_err_wr_buf;
110 * Programming dma (enable send TRWD)
112 if (size > w_buf->size) {
113 raw_spin_unlock_irqrestore(&dev_sem->lock, flags);
114 ERROR_MSG("%s: link: %d RDMA_E_SIZE size(0x%016lx) > w_buf->size(0x%016lx)\n",
115 __FUNCTION__, link, size, w_buf->size);
116 parm->err_no = RDMA_E_SIZE;
117 ret = -EMSGSIZE;
118 goto exit_err_wr_buf;
120 if (size > SMALL_CHANGE) {
121 pd->size_trans = (w_pool_buf->tm_mode ?
122 ALIGN(size, (rdma_link->align_buf_tm * PAGE_SIZE)) : allign_dma(size));
123 } else {
124 pd->size_trans = allign_dma(size);
126 WR_DBG("%s: link: %d : pd->size_trans: 0x%08x\n", __FUNCTION__, link,
127 pd->size_trans);
129 * Create TRWD
131 sending_msg = MSG_TRWD | size;
133 * Send TRWD. ðÏÄÕÍÁÔØ ËÏÇÄÁ ÏÔÐÒÁ×ÌÅÎÏ, ÎÏ READY ÎÅ ÐÏÌÕÞÅÎÏ
135 pd->int_ac = 2;
136 if ((ret_smsg = send_msg_check(sending_msg, link, 0, dev_sem, 0)) > 0) {
137 event_write(link, WRITE_SNDNGMSG_EVENT, ret_smsg, dev_sem->num_obmen);
138 goto wait_env;
140 event_write(link, WRITE_SNDMSGBAD_EVENT, ret_smsg, dev_sem->num_obmen);
141 //raw_spin_unlock_irqrestore(&dev_sem->lock, flags);
142 if (ret_smsg < 0) {
143 pd->trwd_was = 0;
144 CLEAR_PD
145 raw_spin_unlock_irqrestore(&dev_sem->lock, flags);
146 ERROR_MSG("%s: link: %d RDMA_E_MSF_WRD error send TRWD: %d\n",
147 __FUNCTION__, link, ret_smsg);
148 parm->err_no = RDMA_E_MSF_WRD;
149 ret = -EIO;
150 if (ev_pr)
151 get_event_rdma(1);
152 goto exit_err_wr_buf;
154 if (ret_smsg == 0) {
155 CLEAR_PD
156 raw_spin_unlock_irqrestore(&dev_sem->lock, flags);
157 ERROR_MSG("%s: link: %d RDMA_E_TIMER_MAX error send TRWD: %d\n",
158 __FUNCTION__, link, ret_smsg);
159 parm->err_no = RDMA_E_TIMER_MAX;
160 parm->acclen = count_read_sm_max;
161 ret = -EIO;
162 if (ev_pr)
163 get_event_rdma(1);
164 goto exit_err_wr_buf;
166 wait_env:
167 dev_sem->num_obmen++;
168 pst->send_trwd++;
171 * Wait end dma. Wake up TDC. ôÁÊÍÁÕÔ ÐÏÒÑÄËÁ ~2 ÓÅËÕÎÄ. ô.Ë. TRWD
172 * ÏÔÐÒÁ×ÌÑÅÔÓÑ ÔÏÌØËÏ ÐÒÉ ÎÁÌÉÞÉÉ Ó×ÏÂÏÄÎÏÇÏ ÂÕÆÅÒÁ ÎÁ ÐÒÉÅÍÎÏÊ
173 * ÓÔÏÒÏÎÅ É ÏÂÍÅÎ ÐÒÏÈÏÄÉÔ ÂÅÚ ÐÅÒÅÈÏÄÁ × ÐÏÌØÚÏ×ÁÔÅÌØÓËÉÊ ËÏÎÔÅËÓÔ,
174 * ÔÏ ×ÒÅÍÑ ÐÒÏÂÕÖÄÅÎÉÑ ÎÅ ÄÏÌÖÎÏ ÐÒÅ×ÙÛÁÔØ ÓÕÍÍÙ ×ÒÅÍÅÎ Ä×ÕÈ
175 * ÐÒÅÒÙ×ÁÎÉÊ, ×ÒÅÍÅÎÉ ÐÅÒÅÄÁÞÉ Ä×ÕÈ ÓÏÏÂÝÅÎÉÊ É ×ÒÅÍÅÎÉ ÎÁ ÐÅÒÅÄÁÞÕ
176 * ÄÁÎÎÙÈ.
178 int timeout_wait_write_dma;
179 //timeout_wait_write_dma = TIME_OUT_WAIT_WR + (pd->size_trans >> SHIFT_TO);
180 timeout_wait_write_dma = TIME_OUT_WAIT_WR_SEC * HZ;
181 ret_time_dwait = wait_for_irq_rdma_sem(dev_sem, (signed long)timeout_wait_write_dma,
182 link);
183 if (dev_sem->irq_count_rdma != 1) {
184 ERROR_MSG("%s: link: %d MSG wait_2 bad irq "
185 "dev_sem->irq_count_rdma: 0x%08x\n",
186 __FUNCTION__, link, dev_sem->irq_count_rdma);
187 dev_sem->irq_count_rdma = 0;
188 if (ev_pr)
189 get_event_rdma(1);
190 } else {
191 dev_sem->irq_count_rdma = 0;
193 if (ret_time_dwait < 0) {
194 pd->trwd_was = 0;
195 CLEAR_PD
196 raw_spin_unlock_irqrestore(&dev_sem->lock, flags);
197 event_write(link, WRITE_BAD2_EVENT, -ret_time_dwait,
198 dev_sem->num_obmen);
199 switch (ret_time_dwait) {
200 case -1:
201 ERROR_MSG("%s: link: %d DMA RDMA_E_TIMER_IO num_obmen: 0x%08x\n",
202 __FUNCTION__, link, dev_sem->num_obmen);
203 parm->err_no = RDMA_E_TIMER_IO;
204 ret = -ETIME;
205 break;
206 case -2:
207 ERROR_MSG("%s: link: %d DMA RDMA_E_SIGNAL num_obmen: 0x%08x\n",
208 __FUNCTION__, link, dev_sem->num_obmen);
209 parm->err_no = RDMA_E_SIGNAL;
210 ret = -EINTR;
211 break;
212 default:
213 ERROR_MSG("%s: link: %d DMA RDMA_E_SPIN num_obmen: 0x%08x\n",
214 __FUNCTION__, link, dev_sem->num_obmen);
215 parm->err_no = RDMA_E_SPIN;
216 ret = -EAGAIN;
218 if (ev_pr)
219 get_event_rdma(1);
220 goto exit_err_wr_buf;
222 CLEAR_PD
223 raw_spin_unlock_irqrestore(&dev_sem->lock, flags);
225 WR_DBG("%s: link: %d size: 0x%016lx tdc OK\n", __FUNCTION__, link, size);
226 parm->err_no = RDMA_E_SUCCESS;
227 ret = size;
228 exit_err_wr_buf:
229 event_write(link, WRITE_0_EVENT, ret, dev_sem->num_obmen);
230 //get_event_rdma(1);
231 return ret;