]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/c_can_irq.c
Actual driver code for directly mapped SJA1000 into PCI mem region 0.
[lincan.git] / lincan / src / c_can_irq.c
1 /**************************************************************************/
2 /* File: c_can_irq.c - generic IRQ C_CAN Bosch IP core handling           */
3 /*                                                                        */
4 /* LinCAN - (Not only) Linux CAN bus driver                               */
5 /* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz>   */
6 /* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz>             */
7 /* Copyright (C) 2004 Sebastian Stolzenberg <stolzi@sebastian-stolzenberg.de> */
8 /* Funded by OCERA and FRESCOR IST projects                               */
9 /* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl>      */
10 /* and Ake Hedman, eurosource <akhe@eurosource.se>                        */
11 /*                                                                        */
12 /* LinCAN is free software; you can redistribute it and/or modify it      */
13 /* under terms of the GNU General Public License as published by the      */
14 /* Free Software Foundation; either version 2, or (at your option) any    */
15 /* later version.  LinCAN is distributed in the hope that it will be      */
16 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty    */
17 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU    */
18 /* General Public License for more details. You should have received a    */
19 /* copy of the GNU General Public License along with LinCAN; see file     */
20 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
21 /* Cambridge, MA 02139, USA.                                              */
22 /*                                                                        */
23 /* To allow use of LinCAN in the compact embedded systems firmware        */
24 /* and RT-executives (RTEMS for example), main authors agree with next    */
25 /* special exception:                                                     */
26 /*                                                                        */
27 /* Including LinCAN header files in a file, instantiating LinCAN generics */
28 /* or templates, or linking other files with LinCAN objects to produce    */
29 /* an application image/executable, does not by itself cause the          */
30 /* resulting application image/executable to be covered by                */
31 /* the GNU General Public License.                                        */
32 /* This exception does not however invalidate any other reasons           */
33 /* why the executable file might be covered by the GNU Public License.    */
34 /* Publication of enhanced or derived LinCAN files is required although.  */
35 /**************************************************************************/
36
37 #include "../include/can.h"
38 #include "../include/can_sysdep.h"
39 #include "../include/main.h"
40 #include "../include/c_can.h"
41
42 union c_can_data {
43         unsigned short wdata[4];
44         unsigned char bdata[8];
45 };
46
47 // prototypes
48 inline void c_can_irq_read_handler(struct canchip_t *pchip, int idxobj,
49                                    u32 msgid);
50
51 inline void c_can_irq_write_handler(struct canchip_t *pchip, int idxobj);
52
53 void c_can_irq_rtr_handler(struct canchip_t *pchip, int idxobj, u32 msgid);
54
55 u16 readMaskCM = IFXCM_ARB | IFXCM_CNTRL | IFXCM_CLRINTPND
56     | IFXCM_TRND | IFXCM_DA | IFXCM_DB;
57
58 u16 msgLstReadMaskCM = IFXCM_CNTRL;
59 u16 msgLstWriteMaskCM = IFXCM_CNTRL | IFXCM_WRRD;
60
61 ///////////////////////////////////////////////////////////////////////////////
62 // c_can_irq_write_handler
63 //
64 // Send a message from the output fifo ( if any ).
65 //
66
67 inline void c_can_irq_write_handler(struct canchip_t *pchip, int idxobj)
68 {
69         int cmd;
70         struct msgobj_t *pmsgobj = pchip->msgobj[idxobj];
71
72         DEBUGMSG("(c%dm%d)calling c_can_irq_write_handler(...)\n",
73                  pchip->chip_idx, pmsgobj->object);
74
75         if (pmsgobj->tx_slot) {
76                 /* Do local transmitted message distribution if enabled */
77                 if (processlocal) {
78                         /* fill CAN message timestamp */
79                         can_filltimestamp(&pmsgobj->tx_slot->msg.timestamp);
80
81                         pmsgobj->tx_slot->msg.flags |= MSG_LOCAL;
82                         canque_filter_msg2edges(pmsgobj->qends,
83                                                 &pmsgobj->tx_slot->msg);
84                 }
85                 /* Free transmitted slot */
86                 canque_free_outslot(pmsgobj->qends, pmsgobj->tx_qedge,
87                                     pmsgobj->tx_slot);
88                 pmsgobj->tx_slot = NULL;
89         }
90         // Get ready to send next message
91         spin_lock(&c_can_spwlock);
92
93         cmd =
94             canque_test_outslot(pmsgobj->qends, &pmsgobj->tx_qedge,
95                                 &pmsgobj->tx_slot);
96         if (cmd < 0) {
97                 DEBUGMSG("(c%dm%d)Nothin to write\n",
98                          pchip->chip_idx, pmsgobj->object);
99                 spin_unlock(&c_can_spwlock);
100                 return;
101         }
102         // Send the message
103         if (pchip->chipspecops->
104             send_msg(pchip, pmsgobj, &pmsgobj->tx_slot->msg)) {
105                 pmsgobj->ret = -1;
106                 canque_notify_inends(pmsgobj->tx_qedge,
107                                      CANQUEUE_NOTIFY_ERRTX_SEND);
108                 canque_free_outslot(pmsgobj->qends, pmsgobj->tx_qedge,
109                                     pmsgobj->tx_slot);
110                 pmsgobj->tx_slot = NULL;
111                 spin_unlock(&c_can_spwlock);
112                 DEBUGMSG("(c%dm%d)c_can_irq_handler: Unable to send message\n",
113                          pchip->chip_idx, pmsgobj->object);
114                 return;
115         } else {
116                 // Another message sent
117 #ifdef CAN_WITH_STATISTICS
118                 pchip->stat.cntTxPkt++;
119                 pchip->stat.cntTxData += pmsgobj->tx_slot->length;
120 #endif /*CAN_WITH_STATISTICS */
121         }
122         spin_unlock(&c_can_spwlock);
123
124         // Wake up any waiting writer
125         return;
126 }
127
128 ///////////////////////////////////////////////////////////////////////////////
129 // c_can_irq_read_handler
130 //
131 // Message received form the line. Write it in the input fifo->
132 //
133
134 inline void c_can_irq_read_handler(struct canchip_t *pchip,
135                                    int idxobj, u32 msgid)
136 {
137         int i = 0;
138         u16 bDataAvail = 1;
139         u16 msgCntlReg = 0;
140         union c_can_data readData;
141         struct msgobj_t *pmsgobj = pchip->msgobj[idxobj];
142
143         DEBUGMSG("(c%dm%d)calling c_can_irq_read_handler(...)\n",
144                  pchip->chip_idx, pmsgobj->object);
145
146         while (bDataAvail) {
147
148 #ifdef CAN_WITH_STATISTICS
149                 pchip->stat.cntRxFifoOvr++;
150 #endif /*CAN_WITH_STATISTICS */
151                 // Message length
152                 msgCntlReg = c_can_read_reg_w(pchip, CCIF1DMC);
153
154                 pmsgobj->rx_msg.length = msgCntlReg & 0x000F;
155
156                 // Message id
157                 pmsgobj->rx_msg.id = (u32) msgid;
158
159                 // Fetch message bytes
160                 if (pmsgobj->rx_msg.length > 0)
161                         readData.wdata[0] = c_can_read_reg_w(pchip, CCIF1DA1);
162                 if (pmsgobj->rx_msg.length > 2)
163                         readData.wdata[1] = c_can_read_reg_w(pchip, CCIF1DA2);
164                 if (pmsgobj->rx_msg.length > 4)
165                         readData.wdata[2] = c_can_read_reg_w(pchip, CCIF1DB1);
166                 if (pmsgobj->rx_msg.length > 6)
167                         readData.wdata[3] = c_can_read_reg_w(pchip, CCIF1DB2);
168
169                 for (i = 0; i < pmsgobj->rx_msg.length; i++) {
170                         pmsgobj->rx_msg.data[i] = readData.bdata[i];
171                 }
172                 DEBUGMSG("(c%dm%d)Received Message:\n",
173                          pchip->chip_idx, pmsgobj->object);
174                 DEBUGMSG(" id = %ld\n", pmsgobj->rx_msg.id);
175                 DEBUGMSG(" length = %d\n", pmsgobj->rx_msg.length);
176                 for (i = 0; i < pmsgobj->rx_msg.length; i++)
177                         DEBUGMSG(" data[%d] = 0x%.2x\n", i,
178                                  pmsgobj->rx_msg.data[i]);
179
180                 /* fill CAN message timestamp */
181                 can_filltimestamp(&pmsgobj->rx_msg.timestamp);
182
183                 canque_filter_msg2edges(pmsgobj->qends, &pmsgobj->rx_msg);
184
185 #ifdef CAN_WITH_STATISTICS
186                 // Another received packet
187                 pchip->stat.cntRxPkt++;
188
189                 // Add databytes read to statistics block
190                 pchip->stat.cntRxData += pmsgobj->rx_msg.length;
191 #endif /*CAN_WITH_STATISTICS */
192
193                 // Check if new data arrived
194                 if (c_can_if1_busycheck(pchip)) ;
195                 c_can_write_reg_w(pchip, readMaskCM, CCIF1CM);
196                 c_can_write_reg_w(pchip, idxobj + 1, CCIF1CR);
197                 if (c_can_if1_busycheck(pchip)) ;
198                 if (!((bDataAvail = c_can_read_reg_w(pchip, CCIF1DMC)) &
199                       IFXMC_NEWDAT)) {
200                         break;
201                 }
202
203                 if (bDataAvail & IFXMC_MSGLST) {
204                         CANMSG("(c%dm%d)c-can fifo full: Message lost!\n",
205                                pchip->chip_idx, pmsgobj->object);
206                 }
207
208         }
209         // while
210 }
211
212 ///////////////////////////////////////////////////////////////////////////////
213 // c_can_irq_update_filter
214 //
215 // update acceptance filter for given object.
216 //
217
218 void c_can_irq_update_filter(struct canchip_t *pchip, struct msgobj_t *obj)
219 {
220         struct canfilt_t filt;
221
222         if(canqueue_ends_filt_conjuction(obj->qends, &filt)) {
223                 obj->rx_preconfig_id=filt.id;
224
225                 if (filt.flags&MSG_EXT)
226                         can_msgobj_set_fl(obj,RX_MODE_EXT);
227                 else
228                         can_msgobj_clear_fl(obj,RX_MODE_EXT);
229
230                 c_can_mask(obj, filt.mask, 0);
231
232                 c_can_pre_read_config(pchip, obj);
233
234                 CANMSG("c_can_irq_update_filter: obj #%d\n",obj->object);
235         }
236 }
237
238 ///////////////////////////////////////////////////////////////////////////////
239 // c_can_irq_sync_activities
240 //
241 // ensure, that not requests for object activities are serialized.
242 //
243
244 void c_can_irq_sync_activities(struct canchip_t *pchip, struct msgobj_t *obj)
245 {
246         while (!can_msgobj_test_and_set_fl(obj, TX_LOCK)) {
247
248                 if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) {
249                         int cctreqx;
250                         int idxobj = obj->object-1;
251
252                         if(idxobj<0) {
253                                 DEBUGMSG("c_can_irq_sync_activities wrong idxobj\n");
254                                 break;
255                         }
256
257                         if(idxobj < 16)
258                                 cctreqx = c_can_read_reg_w(pchip, CCTREQ1);
259                         else
260                                 cctreqx = c_can_read_reg_w(pchip, CCTREQ2);
261
262                         if (!(cctreqx & (1 << (idxobj & 0xf)))) {
263                                 can_msgobj_clear_fl(obj, TX_REQUEST);
264                                 c_can_irq_write_handler(pchip, idxobj);
265                         }
266                 }
267
268                 if(!obj->tx_slot) {
269                         if(can_msgobj_test_and_clear_fl(obj,FILTCH_REQUEST)) {
270                                 c_can_irq_update_filter(pchip, obj);
271                         }
272                 }
273
274                 can_msgobj_clear_fl(obj, TX_LOCK);
275
276                 mb();
277
278                 if (can_msgobj_test_fl(obj, TX_REQUEST))
279                         continue;
280                 if (can_msgobj_test_fl(obj, FILTCH_REQUEST) && !obj->tx_slot)
281                         continue;
282                 break;
283         }
284 }
285
286 ///////////////////////////////////////////////////////////////////////////////
287 // c_can_irq_handler
288 //
289
290 int c_can_irq_handler(int irq, struct canchip_t *pchip)
291 {
292         struct rtr_id *rtr_search = hardware_p->rtr_queue;
293         u16 chip_status;
294         int id0 = 0, id1 = 0;
295         u16 errcount = 0;
296         u16 irqreg = 0;
297         u32 msgid = 0;
298         u16 tempCntlReg = 0;
299
300         irqreg = c_can_read_reg_w(pchip, CCINTR);
301
302         if (!irqreg) {
303                 DEBUGMSG("\n(c%d)IRQ handler: addr=%.8lx spurious interrupt\n",
304                          pchip->chip_idx,
305                          (long)(pchip-> /*v */ chip_base_addr /* + CCSR */ ));
306                 return CANCHIP_IRQ_NONE;
307         }
308
309         DEBUGMSG("\n(c%d)IRQ handler: addr=%.8lx irqreg=0x%.4x\n",
310                  pchip->chip_idx,
311                  (long)(pchip-> /*v */ chip_base_addr /* + CCSR */ ),
312                  irqreg);
313
314 #ifdef REGDUMP
315         c_can_registerdump(pchip);
316 #endif
317
318         while (irqreg) {
319                 // Handle change in status register
320
321                 if (irqreg == INT_STAT) {
322                         chip_status = c_can_read_reg_w(pchip, CCSR);
323                         DEBUGMSG("(c%d)Status register: 0x%x\n",
324                                  pchip->chip_idx, chip_status);
325
326                         if (chip_status & SR_EWARN) {
327                                 // There is an abnormal # of errors
328 #ifdef CAN_WITH_STATISTICS
329                                 pchip->stat.cntWarnings++;
330 #endif /*CAN_WITH_STATISTICS */
331                                 errcount = c_can_read_reg_w(pchip, CCEC);
332                                 DEBUGMSG
333                                     ("(c%d)stat: c_can_irq_handler: Abnormal number of Errors Warning\n"
334                                      "       txErr=%d, rxErr=%d\n",
335                                      pchip->chip_idx, (errcount & 0x00ff),
336                                      ((errcount & 0x7f00) >> 8));
337
338                                 /*
339                                    // this code deactivates the chip if the transmiterrorcounter grew above 127
340                                    if ((pchip->stat.cntWarnings > 100) && ((errcount&0x00ff) > 127))
341                                    {
342                                    CANMSG("(c%d)to much Errornumber warnings (>100), deactivating chip",
343                                    pchip->chip_idx);
344                                    pchip->config_irqs(pchip, 0);
345                                    pchip->enable_configuration(pchip);
346                                    pchip->clear_objects(pchip);
347                                    pchip->flags &= ~CHANNEL_CONFIGURED;
348                                    return;
349                                    } */
350                         }
351
352                         if (chip_status & SR_EPASS) {
353                                 // There is an abnormal # of errors
354 #ifdef CAN_WITH_STATISTICS
355                                 pchip->stat.cntErrPassive++;
356 #endif /*CAN_WITH_STATISTICS */
357                                 DEBUGMSG
358                                     ("(c%d)stat: c_can_irq_handler: Chip entering Error Passive Mode\n",
359                                      pchip->chip_idx);
360                         }
361
362                         if (chip_status & SR_BOFF) {
363                                 // We have a bus off condition
364 #ifdef CAN_WITH_STATISTICS
365                                 pchip->stat.cntBusOff++;
366 #endif /*CAN_WITH_STATISTICS */
367                                 //pchip->fifo->tx_in_progress = 0;
368                                 //reset init bit
369                                 CANMSG
370                                     ("(c%d)stat: c_can_irq_handler: Bus Off\n",
371                                      pchip->chip_idx);
372                                 /*if (pchip->stat.cntBusOff > 100)
373                                    {
374                                    CANMSG("(c%d)to much busoff warnings (>100), deactivating chip",
375                                    pchip->chip_idx);
376                                    pchip->config_irqs(pchip, 0);
377                                    pchip->enable_configuration(pchip);
378                                    pchip->clear_objects(pchip);
379                                    pchip->flags &= ~CHANNEL_CONFIGURED;
380                                    return;
381                                    }
382                                    else */
383                                 CANMSG("(c%d)try to reconnect",
384                                        pchip->chip_idx);
385                                 pchip->chipspecops->
386                                     disable_configuration(pchip);
387                         }
388
389                         if (chip_status & SR_TXOK) {
390                                 DEBUGMSG
391                                     ("(c%d)stat: Transmitted a Message successfully\n",
392                                      pchip->chip_idx);
393                                 c_can_write_reg_w(pchip, chip_status & ~SR_TXOK,
394                                                   CCSR);
395                         }
396
397                         if (chip_status & SR_RXOK) {
398                                 DEBUGMSG
399                                     ("(c%d)stat: Received a Message successfully\n",
400                                      pchip->chip_idx);
401                                 c_can_write_reg_w(pchip, chip_status & ~SR_RXOK,
402                                                   CCSR);
403                         }
404 #ifdef CAN_WITH_STATISTICS
405                         // Errors to statistics
406                         switch (chip_status & 0x07) {
407                         case SRLEC_NE:  // No error
408                                 break;
409                         case SRLEC_SE:  // Stuff error
410                                 pchip->stat.cntStuffErr++;
411                                 break;
412                         case SRLEC_FE:  // Form error
413                                 pchip->stat.cntFormErr++;
414                                 break;
415                         case SRLEC_AE:  // Ack error
416                                 pchip->stat.cntAckErr++;
417                                 break;
418                         case SRLEC_B1:  // Bit 1 error
419                                 pchip->stat.cntBit1Err++;
420                                 break;
421                         case SRLEC_B0:  // Bit 0 error
422                                 pchip->stat.cntBit0Err++;
423                                 break;
424                         case SRLEC_CR:  // CRC error
425                                 pchip->stat.cntCrcErr++;
426                                 break;
427                         case 7: // unused
428                                 break;
429                         }
430 #endif /*CAN_WITH_STATISTICS */
431                         //return; // continue?
432                 } else {
433                         if (irqreg >= 1 && irqreg <= 32) {
434                                 struct msgobj_t *pmsgobj;
435                                 int idxobj;
436
437                                 //get id
438                                 idxobj = irqreg - 1;
439                                 pmsgobj = pchip->msgobj[idxobj];
440
441                                 //DEBUGMSG( "Interrupt handler: addr=%lx devid=%lx irqreq=%x status=0x%x\n",
442                                 //            (unsigned long)pchip->vbase_addr + iIRQ,
443                                 //      (unsigned long)dev_id,
444                                 //      irqreg,
445                                 //      statreg );
446                                 //
447                                 spin_lock(&c_can_if1lock);
448
449                                 //Message Lost Check
450                                 if (c_can_if1_busycheck(pchip)) ;       /*?????????? */
451                                 c_can_write_reg_w(pchip, msgLstReadMaskCM,
452                                                   CCIF1CM);
453                                 c_can_write_reg_w(pchip, idxobj + 1, CCIF1CR);
454
455                                 if (c_can_if1_busycheck(pchip)) ;       /*?????????? */
456                                 tempCntlReg = c_can_read_reg_w(pchip, CCIF1DMC);
457
458                                 if (tempCntlReg & IFXMC_MSGLST) {
459                                         CANMSG("(c%dm%d)Chip lost a message\n",
460                                                pchip->chip_idx,
461                                                pmsgobj->object);
462 #ifdef CAN_WITH_STATISTICS
463                                         pchip->stat.cntMsgLst++;
464 #endif /*CAN_WITH_STATISTICS */
465
466                                         //Reset Message Lost Bit
467                                         tempCntlReg =
468                                             tempCntlReg & (~IFXMC_MSGLST);
469                                         c_can_write_reg_w(pchip, tempCntlReg,
470                                                           CCIF1DMC);
471                                         c_can_write_reg_w(pchip,
472                                                           msgLstWriteMaskCM,
473                                                           CCIF1CM);
474                                         c_can_write_reg_w(pchip, idxobj + 1,
475                                                           CCIF1CR);
476                                 }
477                                 //transfer Message Object to IF1 Buffer
478                                 if (c_can_if1_busycheck(pchip)) ;
479
480                                 c_can_write_reg_w(pchip, readMaskCM, CCIF1CM);
481                                 c_can_write_reg_w(pchip, idxobj + 1, CCIF1CR);
482
483                                 if (c_can_if1_busycheck(pchip)) ;
484                                 if (c_can_read_reg_w(pchip, CCIF1A2) &
485                                     IFXARB2_DIR) {
486                                         DEBUGMSG("c_can_irq_write_handler idxobj=%d, msgid=%d\n",idxobj,msgid);
487                                         spin_unlock(&c_can_if1lock);
488                                         c_can_irq_write_handler(pchip, idxobj);
489
490                                         if(!pmsgobj->tx_slot){
491                                                 if(can_msgobj_test_and_clear_fl(pmsgobj, FILTCH_REQUEST)) {
492                                                         c_can_irq_update_filter(pchip, pmsgobj);
493                                                 }
494                                         }
495                                 } else {
496                                         if (can_msgobj_test_fl
497                                             (pmsgobj, RX_MODE_EXT)) {
498                                                 id0 =
499                                                     c_can_read_reg_w(pchip,
500                                                                      CCIF1A1);
501                                                 id1 =
502                                                     (c_can_read_reg_w
503                                                      (pchip,
504                                                       CCIF1A2) & 0x1FFF) << 16;
505                                                 msgid = id0 | id1;
506                                         } else {
507                                                 msgid =
508                                                     ((c_can_read_reg_w
509                                                       (pchip,
510                                                        CCIF1A2) & 0x1FFC) >> 2)
511                                                     & 0x7FF;
512                                         }
513                                         spin_unlock(&c_can_if1lock);
514
515                                         spin_lock(&hardware_p->rtr_lock);
516                                         while (rtr_search != NULL) {
517                                                 if (rtr_search->id == msgid) {
518                                                         break;
519                                                 }
520                                                 rtr_search = rtr_search->next;
521                                         }
522                                         spin_unlock(&hardware_p->rtr_lock);
523
524                                         spin_lock(&c_can_if1lock);
525
526                                         //transfer Message Object to IF1 Buffer
527                                         if (c_can_if1_busycheck(pchip)) ;
528                                         c_can_write_reg_w(pchip, readMaskCM,
529                                                           CCIF1CM);
530                                         c_can_write_reg_w(pchip, idxobj + 1,
531                                                           CCIF1CR);
532
533                                         if (c_can_if1_busycheck(pchip)) ;
534
535                                         if ((rtr_search != NULL)
536                                             && (rtr_search->id == msgid)) {
537                                                 c_can_irq_rtr_handler(pchip,
538                                                                       idxobj,
539                                                                       msgid);
540                                         } else {
541                                                 c_can_irq_read_handler(pchip,
542                                                                        idxobj,
543                                                                        msgid);
544                                         }
545                                         spin_unlock(&c_can_if1lock);
546
547                                 }
548                                 //else
549                         }
550                         //if (irqreg >= 1 && irqreg <= 32)
551                 }
552                 // Get irq status again
553                 irqreg = c_can_read_reg_w(pchip, CCINTR);
554         }
555         return CANCHIP_IRQ_HANDLED;
556 }
557
558 ///////////////////////////////////////////////////////////////////////////////
559 // c_can_irq_rtr_handler
560 //
561
562 void c_can_irq_rtr_handler(struct canchip_t *pchip, int idxobj, u32 msgid)
563 {
564         short int i = 0;
565         struct rtr_id *prtr_search = hardware_p->rtr_queue;
566         union c_can_data rtrData;
567
568         spin_lock(&hardware_p->rtr_lock);
569
570         prtr_search->rtr_message->id = msgid;
571         prtr_search->rtr_message->length =
572             (c_can_read_reg_w(pchip, CCIF1DMC) & 0x000f);
573
574         // Fetch message bytes
575         if (prtr_search->rtr_message->length > 0)
576                 rtrData.wdata[0] = c_can_read_reg_w(pchip, CCIF1DA1);
577         if (prtr_search->rtr_message->length > 2)
578                 rtrData.wdata[1] = c_can_read_reg_w(pchip, CCIF1DA2);
579         if (prtr_search->rtr_message->length > 4)
580                 rtrData.wdata[2] = c_can_read_reg_w(pchip, CCIF1DB1);
581         if (prtr_search->rtr_message->length > 6)
582                 rtrData.wdata[3] = c_can_read_reg_w(pchip, CCIF1DB2);
583
584         for (i = 0; i < prtr_search->rtr_message->length; i++) {
585                 prtr_search->rtr_message->data[i] = rtrData.bdata[i];
586         }
587
588         spin_unlock(&hardware_p->rtr_lock);
589         wake_up_interruptible(&prtr_search->rtr_wq);
590         return;
591 }