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