1
2
3
4
5
6
7
8
9
10
11
12#include <linux/delay.h>
13#include <linux/firmware.h>
14#include <linux/slab.h>
15#include <misc/altera.h>
16#include "altera-exprt.h"
17#include "altera-jtag.h"
18
19#define alt_jtag_io(a, b, c)\
20 astate->config->jtag_io(astate->config->dev, a, b, c);
21
22#define alt_malloc(a) kzalloc(a, GFP_KERNEL);
23
24
25
26
27
28
29struct altera_jtag_machine {
30 enum altera_jtag_state tms_high;
31 enum altera_jtag_state tms_low;
32};
33
34static const struct altera_jtag_machine altera_transitions[] = {
35 { RESET, IDLE },
36 { DRSELECT, IDLE },
37 { IRSELECT, DRCAPTURE },
38 { DREXIT1, DRSHIFT },
39 { DREXIT1, DRSHIFT },
40 { DRUPDATE, DRPAUSE },
41 { DREXIT2, DRPAUSE },
42 { DRUPDATE, DRSHIFT },
43 { DRSELECT, IDLE },
44 { RESET, IRCAPTURE },
45 { IREXIT1, IRSHIFT },
46 { IREXIT1, IRSHIFT },
47 { IRUPDATE, IRPAUSE },
48 { IREXIT2, IRPAUSE },
49 { IRUPDATE, IRSHIFT },
50 { DRSELECT, IDLE }
51};
52
53
54
55
56
57
58
59
60static const u16 altera_jtag_path_map[16] = {
61
62 0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFFFF,
63
64 0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0xFFFF, 0x7FFD
65};
66
67
68#define TMS_HIGH 1
69#define TMS_LOW 0
70#define TDI_HIGH 1
71#define TDI_LOW 0
72#define READ_TDO 1
73#define IGNORE_TDO 0
74
75int altera_jinit(struct altera_state *astate)
76{
77 struct altera_jtag *js = &astate->js;
78
79
80 js->jtag_state = ILLEGAL_JTAG_STATE;
81
82
83 js->drstop_state = IDLE;
84 js->irstop_state = IDLE;
85 js->dr_pre = 0;
86 js->dr_post = 0;
87 js->ir_pre = 0;
88 js->ir_post = 0;
89 js->dr_length = 0;
90 js->ir_length = 0;
91
92 js->dr_pre_data = NULL;
93 js->dr_post_data = NULL;
94 js->ir_pre_data = NULL;
95 js->ir_post_data = NULL;
96 js->dr_buffer = NULL;
97 js->ir_buffer = NULL;
98
99 return 0;
100}
101
102int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
103{
104 js->drstop_state = state;
105
106 return 0;
107}
108
109int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
110{
111 js->irstop_state = state;
112
113 return 0;
114}
115
116int altera_set_dr_pre(struct altera_jtag *js,
117 u32 count, u32 start_index,
118 u8 *preamble_data)
119{
120 int status = 0;
121 u32 i;
122 u32 j;
123
124 if (count > js->dr_pre) {
125 kfree(js->dr_pre_data);
126 js->dr_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
127 if (js->dr_pre_data == NULL)
128 status = -ENOMEM;
129 else
130 js->dr_pre = count;
131 } else
132 js->dr_pre = count;
133
134 if (status == 0) {
135 for (i = 0; i < count; ++i) {
136 j = i + start_index;
137
138 if (preamble_data == NULL)
139 js->dr_pre_data[i >> 3] |= (1 << (i & 7));
140 else {
141 if (preamble_data[j >> 3] & (1 << (j & 7)))
142 js->dr_pre_data[i >> 3] |=
143 (1 << (i & 7));
144 else
145 js->dr_pre_data[i >> 3] &=
146 ~(u32)(1 << (i & 7));
147
148 }
149 }
150 }
151
152 return status;
153}
154
155int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
156 u8 *preamble_data)
157{
158 int status = 0;
159 u32 i;
160 u32 j;
161
162 if (count > js->ir_pre) {
163 kfree(js->ir_pre_data);
164 js->ir_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
165 if (js->ir_pre_data == NULL)
166 status = -ENOMEM;
167 else
168 js->ir_pre = count;
169
170 } else
171 js->ir_pre = count;
172
173 if (status == 0) {
174 for (i = 0; i < count; ++i) {
175 j = i + start_index;
176 if (preamble_data == NULL)
177 js->ir_pre_data[i >> 3] |= (1 << (i & 7));
178 else {
179 if (preamble_data[j >> 3] & (1 << (j & 7)))
180 js->ir_pre_data[i >> 3] |=
181 (1 << (i & 7));
182 else
183 js->ir_pre_data[i >> 3] &=
184 ~(u32)(1 << (i & 7));
185
186 }
187 }
188 }
189
190 return status;
191}
192
193int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
194 u8 *postamble_data)
195{
196 int status = 0;
197 u32 i;
198 u32 j;
199
200 if (count > js->dr_post) {
201 kfree(js->dr_post_data);
202 js->dr_post_data = (u8 *)alt_malloc((count + 7) >> 3);
203
204 if (js->dr_post_data == NULL)
205 status = -ENOMEM;
206 else
207 js->dr_post = count;
208
209 } else
210 js->dr_post = count;
211
212 if (status == 0) {
213 for (i = 0; i < count; ++i) {
214 j = i + start_index;
215
216 if (postamble_data == NULL)
217 js->dr_post_data[i >> 3] |= (1 << (i & 7));
218 else {
219 if (postamble_data[j >> 3] & (1 << (j & 7)))
220 js->dr_post_data[i >> 3] |=
221 (1 << (i & 7));
222 else
223 js->dr_post_data[i >> 3] &=
224 ~(u32)(1 << (i & 7));
225
226 }
227 }
228 }
229
230 return status;
231}
232
233int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
234 u8 *postamble_data)
235{
236 int status = 0;
237 u32 i;
238 u32 j;
239
240 if (count > js->ir_post) {
241 kfree(js->ir_post_data);
242 js->ir_post_data = (u8 *)alt_malloc((count + 7) >> 3);
243 if (js->ir_post_data == NULL)
244 status = -ENOMEM;
245 else
246 js->ir_post = count;
247
248 } else
249 js->ir_post = count;
250
251 if (status != 0)
252 return status;
253
254 for (i = 0; i < count; ++i) {
255 j = i + start_index;
256
257 if (postamble_data == NULL)
258 js->ir_post_data[i >> 3] |= (1 << (i & 7));
259 else {
260 if (postamble_data[j >> 3] & (1 << (j & 7)))
261 js->ir_post_data[i >> 3] |= (1 << (i & 7));
262 else
263 js->ir_post_data[i >> 3] &=
264 ~(u32)(1 << (i & 7));
265
266 }
267 }
268
269 return status;
270}
271
272static void altera_jreset_idle(struct altera_state *astate)
273{
274 struct altera_jtag *js = &astate->js;
275 int i;
276
277 for (i = 0; i < 5; ++i)
278 alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
279
280
281 alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
282 js->jtag_state = IDLE;
283}
284
285int altera_goto_jstate(struct altera_state *astate,
286 enum altera_jtag_state state)
287{
288 struct altera_jtag *js = &astate->js;
289 int tms;
290 int count = 0;
291 int status = 0;
292
293 if (js->jtag_state == ILLEGAL_JTAG_STATE)
294
295 altera_jreset_idle(astate);
296
297 if (js->jtag_state == state) {
298
299
300
301
302
303 if ((state == IDLE) || (state == DRSHIFT) ||
304 (state == DRPAUSE) || (state == IRSHIFT) ||
305 (state == IRPAUSE)) {
306 alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
307 } else if (state == RESET)
308 alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
309
310 } else {
311 while ((js->jtag_state != state) && (count < 9)) {
312
313 tms = (altera_jtag_path_map[js->jtag_state] &
314 (1 << state))
315 ? TMS_HIGH : TMS_LOW;
316
317
318 alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
319
320 if (tms)
321 js->jtag_state =
322 altera_transitions[js->jtag_state].tms_high;
323 else
324 js->jtag_state =
325 altera_transitions[js->jtag_state].tms_low;
326
327 ++count;
328 }
329 }
330
331 if (js->jtag_state != state)
332 status = -EREMOTEIO;
333
334 return status;
335}
336
337int altera_wait_cycles(struct altera_state *astate,
338 s32 cycles,
339 enum altera_jtag_state wait_state)
340{
341 struct altera_jtag *js = &astate->js;
342 int tms;
343 s32 count;
344 int status = 0;
345
346 if (js->jtag_state != wait_state)
347 status = altera_goto_jstate(astate, wait_state);
348
349 if (status == 0) {
350
351
352
353
354 tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW;
355
356 for (count = 0L; count < cycles; count++)
357 alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
358
359 }
360
361 return status;
362}
363
364int altera_wait_msecs(struct altera_state *astate,
365 s32 microseconds, enum altera_jtag_state wait_state)
366
367
368
369
370
371
372
373
374
375{
376 struct altera_jtag *js = &astate->js;
377 int status = 0;
378
379 if ((js->jtag_state != ILLEGAL_JTAG_STATE) &&
380 (js->jtag_state != wait_state))
381 status = altera_goto_jstate(astate, wait_state);
382
383 if (status == 0)
384
385 udelay(microseconds);
386
387 return status;
388}
389
390static void altera_concatenate_data(u8 *buffer,
391 u8 *preamble_data,
392 u32 preamble_count,
393 u8 *target_data,
394 u32 start_index,
395 u32 target_count,
396 u8 *postamble_data,
397 u32 postamble_count)
398
399
400
401
402{
403 u32 i, j, k;
404
405 for (i = 0L; i < preamble_count; ++i) {
406 if (preamble_data[i >> 3L] & (1L << (i & 7L)))
407 buffer[i >> 3L] |= (1L << (i & 7L));
408 else
409 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
410
411 }
412
413 j = start_index;
414 k = preamble_count + target_count;
415 for (; i < k; ++i, ++j) {
416 if (target_data[j >> 3L] & (1L << (j & 7L)))
417 buffer[i >> 3L] |= (1L << (i & 7L));
418 else
419 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
420
421 }
422
423 j = 0L;
424 k = preamble_count + target_count + postamble_count;
425 for (; i < k; ++i, ++j) {
426 if (postamble_data[j >> 3L] & (1L << (j & 7L)))
427 buffer[i >> 3L] |= (1L << (i & 7L));
428 else
429 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
430
431 }
432}
433
434static int alt_jtag_drscan(struct altera_state *astate,
435 int start_state,
436 int count,
437 u8 *tdi,
438 u8 *tdo)
439{
440 int i = 0;
441 int tdo_bit = 0;
442 int status = 1;
443
444
445 switch (start_state) {
446 case 0:
447 alt_jtag_io(1, 0, 0);
448 alt_jtag_io(0, 0, 0);
449 alt_jtag_io(0, 0, 0);
450 break;
451
452 case 1:
453 alt_jtag_io(1, 0, 0);
454 alt_jtag_io(1, 0, 0);
455 alt_jtag_io(1, 0, 0);
456 alt_jtag_io(0, 0, 0);
457 alt_jtag_io(0, 0, 0);
458 break;
459
460 case 2:
461 alt_jtag_io(1, 0, 0);
462 alt_jtag_io(1, 0, 0);
463 alt_jtag_io(1, 0, 0);
464 alt_jtag_io(0, 0, 0);
465 alt_jtag_io(0, 0, 0);
466 break;
467
468 default:
469 status = 0;
470 }
471
472 if (status) {
473
474 for (i = 0; i < count; i++) {
475 tdo_bit = alt_jtag_io(
476 (i == count - 1),
477 tdi[i >> 3] & (1 << (i & 7)),
478 (tdo != NULL));
479
480 if (tdo != NULL) {
481 if (tdo_bit)
482 tdo[i >> 3] |= (1 << (i & 7));
483 else
484 tdo[i >> 3] &= ~(u32)(1 << (i & 7));
485
486 }
487 }
488
489 alt_jtag_io(0, 0, 0);
490 }
491
492 return status;
493}
494
495static int alt_jtag_irscan(struct altera_state *astate,
496 int start_state,
497 int count,
498 u8 *tdi,
499 u8 *tdo)
500{
501 int i = 0;
502 int tdo_bit = 0;
503 int status = 1;
504
505
506 switch (start_state) {
507 case 0:
508 alt_jtag_io(1, 0, 0);
509 alt_jtag_io(1, 0, 0);
510 alt_jtag_io(0, 0, 0);
511 alt_jtag_io(0, 0, 0);
512 break;
513
514 case 1:
515 alt_jtag_io(1, 0, 0);
516 alt_jtag_io(1, 0, 0);
517 alt_jtag_io(1, 0, 0);
518 alt_jtag_io(1, 0, 0);
519 alt_jtag_io(0, 0, 0);
520 alt_jtag_io(0, 0, 0);
521 break;
522
523 case 2:
524 alt_jtag_io(1, 0, 0);
525 alt_jtag_io(1, 0, 0);
526 alt_jtag_io(1, 0, 0);
527 alt_jtag_io(1, 0, 0);
528 alt_jtag_io(0, 0, 0);
529 alt_jtag_io(0, 0, 0);
530 break;
531
532 default:
533 status = 0;
534 }
535
536 if (status) {
537
538 for (i = 0; i < count; i++) {
539 tdo_bit = alt_jtag_io(
540 (i == count - 1),
541 tdi[i >> 3] & (1 << (i & 7)),
542 (tdo != NULL));
543 if (tdo != NULL) {
544 if (tdo_bit)
545 tdo[i >> 3] |= (1 << (i & 7));
546 else
547 tdo[i >> 3] &= ~(u32)(1 << (i & 7));
548
549 }
550 }
551
552 alt_jtag_io(0, 0, 0);
553 }
554
555 return status;
556}
557
558static void altera_extract_target_data(u8 *buffer,
559 u8 *target_data,
560 u32 start_index,
561 u32 preamble_count,
562 u32 target_count)
563
564
565
566
567{
568 u32 i;
569 u32 j;
570 u32 k;
571
572 j = preamble_count;
573 k = start_index + target_count;
574 for (i = start_index; i < k; ++i, ++j) {
575 if (buffer[j >> 3] & (1 << (j & 7)))
576 target_data[i >> 3] |= (1 << (i & 7));
577 else
578 target_data[i >> 3] &= ~(u32)(1 << (i & 7));
579
580 }
581}
582
583int altera_irscan(struct altera_state *astate,
584 u32 count,
585 u8 *tdi_data,
586 u32 start_index)
587
588{
589 struct altera_jtag *js = &astate->js;
590 int start_code = 0;
591 u32 alloc_chars = 0;
592 u32 shift_count = js->ir_pre + count + js->ir_post;
593 int status = 0;
594 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
595
596 switch (js->jtag_state) {
597 case ILLEGAL_JTAG_STATE:
598 case RESET:
599 case IDLE:
600 start_code = 0;
601 start_state = IDLE;
602 break;
603
604 case DRSELECT:
605 case DRCAPTURE:
606 case DRSHIFT:
607 case DREXIT1:
608 case DRPAUSE:
609 case DREXIT2:
610 case DRUPDATE:
611 start_code = 1;
612 start_state = DRPAUSE;
613 break;
614
615 case IRSELECT:
616 case IRCAPTURE:
617 case IRSHIFT:
618 case IREXIT1:
619 case IRPAUSE:
620 case IREXIT2:
621 case IRUPDATE:
622 start_code = 2;
623 start_state = IRPAUSE;
624 break;
625
626 default:
627 status = -EREMOTEIO;
628 break;
629 }
630
631 if (status == 0)
632 if (js->jtag_state != start_state)
633 status = altera_goto_jstate(astate, start_state);
634
635 if (status == 0) {
636 if (shift_count > js->ir_length) {
637 alloc_chars = (shift_count + 7) >> 3;
638 kfree(js->ir_buffer);
639 js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
640 if (js->ir_buffer == NULL)
641 status = -ENOMEM;
642 else
643 js->ir_length = alloc_chars * 8;
644
645 }
646 }
647
648 if (status == 0) {
649
650
651
652
653 altera_concatenate_data(js->ir_buffer,
654 js->ir_pre_data,
655 js->ir_pre,
656 tdi_data,
657 start_index,
658 count,
659 js->ir_post_data,
660 js->ir_post);
661
662 alt_jtag_irscan(astate,
663 start_code,
664 shift_count,
665 js->ir_buffer,
666 NULL);
667
668
669 js->jtag_state = IRPAUSE;
670 }
671
672 if (status == 0)
673 if (js->irstop_state != IRPAUSE)
674 status = altera_goto_jstate(astate, js->irstop_state);
675
676
677 return status;
678}
679
680int altera_swap_ir(struct altera_state *astate,
681 u32 count,
682 u8 *in_data,
683 u32 in_index,
684 u8 *out_data,
685 u32 out_index)
686
687{
688 struct altera_jtag *js = &astate->js;
689 int start_code = 0;
690 u32 alloc_chars = 0;
691 u32 shift_count = js->ir_pre + count + js->ir_post;
692 int status = 0;
693 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
694
695 switch (js->jtag_state) {
696 case ILLEGAL_JTAG_STATE:
697 case RESET:
698 case IDLE:
699 start_code = 0;
700 start_state = IDLE;
701 break;
702
703 case DRSELECT:
704 case DRCAPTURE:
705 case DRSHIFT:
706 case DREXIT1:
707 case DRPAUSE:
708 case DREXIT2:
709 case DRUPDATE:
710 start_code = 1;
711 start_state = DRPAUSE;
712 break;
713
714 case IRSELECT:
715 case IRCAPTURE:
716 case IRSHIFT:
717 case IREXIT1:
718 case IRPAUSE:
719 case IREXIT2:
720 case IRUPDATE:
721 start_code = 2;
722 start_state = IRPAUSE;
723 break;
724
725 default:
726 status = -EREMOTEIO;
727 break;
728 }
729
730 if (status == 0)
731 if (js->jtag_state != start_state)
732 status = altera_goto_jstate(astate, start_state);
733
734 if (status == 0) {
735 if (shift_count > js->ir_length) {
736 alloc_chars = (shift_count + 7) >> 3;
737 kfree(js->ir_buffer);
738 js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
739 if (js->ir_buffer == NULL)
740 status = -ENOMEM;
741 else
742 js->ir_length = alloc_chars * 8;
743
744 }
745 }
746
747 if (status == 0) {
748
749
750
751
752 altera_concatenate_data(js->ir_buffer,
753 js->ir_pre_data,
754 js->ir_pre,
755 in_data,
756 in_index,
757 count,
758 js->ir_post_data,
759 js->ir_post);
760
761
762 alt_jtag_irscan(astate,
763 start_code,
764 shift_count,
765 js->ir_buffer,
766 js->ir_buffer);
767
768
769 js->jtag_state = IRPAUSE;
770 }
771
772 if (status == 0)
773 if (js->irstop_state != IRPAUSE)
774 status = altera_goto_jstate(astate, js->irstop_state);
775
776
777 if (status == 0)
778
779 altera_extract_target_data(js->ir_buffer,
780 out_data, out_index,
781 js->ir_pre, count);
782
783 return status;
784}
785
786int altera_drscan(struct altera_state *astate,
787 u32 count,
788 u8 *tdi_data,
789 u32 start_index)
790
791{
792 struct altera_jtag *js = &astate->js;
793 int start_code = 0;
794 u32 alloc_chars = 0;
795 u32 shift_count = js->dr_pre + count + js->dr_post;
796 int status = 0;
797 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
798
799 switch (js->jtag_state) {
800 case ILLEGAL_JTAG_STATE:
801 case RESET:
802 case IDLE:
803 start_code = 0;
804 start_state = IDLE;
805 break;
806
807 case DRSELECT:
808 case DRCAPTURE:
809 case DRSHIFT:
810 case DREXIT1:
811 case DRPAUSE:
812 case DREXIT2:
813 case DRUPDATE:
814 start_code = 1;
815 start_state = DRPAUSE;
816 break;
817
818 case IRSELECT:
819 case IRCAPTURE:
820 case IRSHIFT:
821 case IREXIT1:
822 case IRPAUSE:
823 case IREXIT2:
824 case IRUPDATE:
825 start_code = 2;
826 start_state = IRPAUSE;
827 break;
828
829 default:
830 status = -EREMOTEIO;
831 break;
832 }
833
834 if (status == 0)
835 if (js->jtag_state != start_state)
836 status = altera_goto_jstate(astate, start_state);
837
838 if (status == 0) {
839 if (shift_count > js->dr_length) {
840 alloc_chars = (shift_count + 7) >> 3;
841 kfree(js->dr_buffer);
842 js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
843 if (js->dr_buffer == NULL)
844 status = -ENOMEM;
845 else
846 js->dr_length = alloc_chars * 8;
847
848 }
849 }
850
851 if (status == 0) {
852
853
854
855
856 altera_concatenate_data(js->dr_buffer,
857 js->dr_pre_data,
858 js->dr_pre,
859 tdi_data,
860 start_index,
861 count,
862 js->dr_post_data,
863 js->dr_post);
864
865 alt_jtag_drscan(astate, start_code, shift_count,
866 js->dr_buffer, NULL);
867
868 js->jtag_state = DRPAUSE;
869 }
870
871 if (status == 0)
872 if (js->drstop_state != DRPAUSE)
873 status = altera_goto_jstate(astate, js->drstop_state);
874
875 return status;
876}
877
878int altera_swap_dr(struct altera_state *astate, u32 count,
879 u8 *in_data, u32 in_index,
880 u8 *out_data, u32 out_index)
881
882{
883 struct altera_jtag *js = &astate->js;
884 int start_code = 0;
885 u32 alloc_chars = 0;
886 u32 shift_count = js->dr_pre + count + js->dr_post;
887 int status = 0;
888 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
889
890 switch (js->jtag_state) {
891 case ILLEGAL_JTAG_STATE:
892 case RESET:
893 case IDLE:
894 start_code = 0;
895 start_state = IDLE;
896 break;
897
898 case DRSELECT:
899 case DRCAPTURE:
900 case DRSHIFT:
901 case DREXIT1:
902 case DRPAUSE:
903 case DREXIT2:
904 case DRUPDATE:
905 start_code = 1;
906 start_state = DRPAUSE;
907 break;
908
909 case IRSELECT:
910 case IRCAPTURE:
911 case IRSHIFT:
912 case IREXIT1:
913 case IRPAUSE:
914 case IREXIT2:
915 case IRUPDATE:
916 start_code = 2;
917 start_state = IRPAUSE;
918 break;
919
920 default:
921 status = -EREMOTEIO;
922 break;
923 }
924
925 if (status == 0)
926 if (js->jtag_state != start_state)
927 status = altera_goto_jstate(astate, start_state);
928
929 if (status == 0) {
930 if (shift_count > js->dr_length) {
931 alloc_chars = (shift_count + 7) >> 3;
932 kfree(js->dr_buffer);
933 js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
934
935 if (js->dr_buffer == NULL)
936 status = -ENOMEM;
937 else
938 js->dr_length = alloc_chars * 8;
939
940 }
941 }
942
943 if (status == 0) {
944
945
946
947
948 altera_concatenate_data(js->dr_buffer,
949 js->dr_pre_data,
950 js->dr_pre,
951 in_data,
952 in_index,
953 count,
954 js->dr_post_data,
955 js->dr_post);
956
957
958 alt_jtag_drscan(astate,
959 start_code,
960 shift_count,
961 js->dr_buffer,
962 js->dr_buffer);
963
964
965 js->jtag_state = DRPAUSE;
966 }
967
968 if (status == 0)
969 if (js->drstop_state != DRPAUSE)
970 status = altera_goto_jstate(astate, js->drstop_state);
971
972 if (status == 0)
973
974 altera_extract_target_data(js->dr_buffer,
975 out_data,
976 out_index,
977 js->dr_pre,
978 count);
979
980 return status;
981}
982
983void altera_free_buffers(struct altera_state *astate)
984{
985 struct altera_jtag *js = &astate->js;
986
987 if (js->jtag_state != ILLEGAL_JTAG_STATE)
988 altera_jreset_idle(astate);
989
990 kfree(js->dr_pre_data);
991 js->dr_pre_data = NULL;
992
993 kfree(js->dr_post_data);
994 js->dr_post_data = NULL;
995
996 kfree(js->dr_buffer);
997 js->dr_buffer = NULL;
998
999 kfree(js->ir_pre_data);
1000 js->ir_pre_data = NULL;
1001
1002 kfree(js->ir_post_data);
1003 js->ir_post_data = NULL;
1004
1005 kfree(js->ir_buffer);
1006 js->ir_buffer = NULL;
1007}
1008