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
27
28
29
30
31
32
33
34#define FORCE_DSA_ALIGNMENT
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233#include <linux/module.h>
234
235#include <linux/config.h>
236
237#include <linux/types.h>
238#include <asm/setup.h>
239#include <asm/dma.h>
240#include <asm/io.h>
241#include <asm/system.h>
242#include <linux/delay.h>
243#include <linux/signal.h>
244#include <linux/sched.h>
245#include <linux/errno.h>
246#include <linux/string.h>
247#include <linux/slab.h>
248#include <linux/vmalloc.h>
249#include <linux/mm.h>
250#include <linux/ioport.h>
251#include <linux/time.h>
252#include <linux/blkdev.h>
253#include <linux/spinlock.h>
254#include <linux/interrupt.h>
255#include <asm/pgtable.h>
256
257#ifdef CONFIG_AMIGA
258#include <asm/amigahw.h>
259#include <asm/amigaints.h>
260#include <asm/irq.h>
261
262#define BIG_ENDIAN
263#define NO_IO_SPACE
264#endif
265
266#ifdef CONFIG_MVME16x
267#include <asm/mvme16xhw.h>
268
269#define BIG_ENDIAN
270#define NO_IO_SPACE
271#define VALID_IDS
272#endif
273
274#ifdef CONFIG_BVME6000
275#include <asm/bvme6000hw.h>
276
277#define BIG_ENDIAN
278#define NO_IO_SPACE
279#define VALID_IDS
280#endif
281
282#include "scsi.h"
283#include <scsi/scsi_host.h>
284#include "53c7xx.h"
285#include <linux/stat.h>
286#include <linux/stddef.h>
287
288#ifdef NO_IO_SPACE
289
290
291
292
293#undef inb
294#undef outb
295#undef inw
296#undef outw
297#undef inl
298#undef outl
299#define inb(x) 1
300#define inw(x) 1
301#define inl(x) 1
302#define outb(x,y) 1
303#define outw(x,y) 1
304#define outl(x,y) 1
305#endif
306
307static int check_address (unsigned long addr, int size);
308static void dump_events (struct Scsi_Host *host, int count);
309static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host,
310 int free, int issue);
311static void hard_reset (struct Scsi_Host *host);
312static void ncr_scsi_reset (struct Scsi_Host *host);
313static void print_lots (struct Scsi_Host *host);
314static void set_synchronous (struct Scsi_Host *host, int target, int sxfer,
315 int scntl3, int now_connected);
316static int datapath_residual (struct Scsi_Host *host);
317static const char * sbcl_to_phase (int sbcl);
318static void print_progress (Scsi_Cmnd *cmd);
319static void print_queues (struct Scsi_Host *host);
320static void process_issue_queue (unsigned long flags);
321static int shutdown (struct Scsi_Host *host);
322static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);
323static int disable (struct Scsi_Host *host);
324static int NCR53c7xx_run_tests (struct Scsi_Host *host);
325static irqreturn_t NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
326static void NCR53c7x0_intfly (struct Scsi_Host *host);
327static int ncr_halt (struct Scsi_Host *host);
328static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd
329 *cmd);
330static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
331static void print_dsa (struct Scsi_Host *host, u32 *dsa,
332 const char *prefix);
333static int print_insn (struct Scsi_Host *host, const u32 *insn,
334 const char *prefix, int kernel);
335
336static void NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd);
337static void NCR53c7x0_init_fixup (struct Scsi_Host *host);
338static int NCR53c7x0_dstat_sir_intr (struct Scsi_Host *host, struct
339 NCR53c7x0_cmd *cmd);
340static void NCR53c7x0_soft_reset (struct Scsi_Host *host);
341
342
343static int track_events = 0;
344static struct Scsi_Host *first_host = NULL;
345static Scsi_Host_Template *the_template = NULL;
346
347
348
349#include "53c7xx_d.h"
350#ifdef A_int_debug_sync
351#define DEBUG_SYNC_INTR A_int_debug_sync
352#endif
353int NCR53c7xx_script_len = sizeof (SCRIPT);
354int NCR53c7xx_dsa_len = A_dsa_end + Ent_dsa_zero - Ent_dsa_code_template;
355#ifdef FORCE_DSA_ALIGNMENT
356int CmdPageStart = (0 - Ent_dsa_zero - sizeof(struct NCR53c7x0_cmd)) & 0xff;
357#endif
358
359static char *setup_strings[] =
360 {"","","","","","","",""};
361
362#define MAX_SETUP_STRINGS (sizeof(setup_strings) / sizeof(char *))
363#define SETUP_BUFFER_SIZE 200
364static char setup_buffer[SETUP_BUFFER_SIZE];
365static char setup_used[MAX_SETUP_STRINGS];
366
367void ncr53c7xx_setup (char *str, int *ints)
368{
369 int i;
370 char *p1, *p2;
371
372 p1 = setup_buffer;
373 *p1 = '\0';
374 if (str)
375 strncpy(p1, str, SETUP_BUFFER_SIZE - strlen(setup_buffer));
376 setup_buffer[SETUP_BUFFER_SIZE - 1] = '\0';
377 p1 = setup_buffer;
378 i = 0;
379 while (*p1 && (i < MAX_SETUP_STRINGS)) {
380 p2 = strchr(p1, ',');
381 if (p2) {
382 *p2 = '\0';
383 if (p1 != p2)
384 setup_strings[i] = p1;
385 p1 = p2 + 1;
386 i++;
387 }
388 else {
389 setup_strings[i] = p1;
390 break;
391 }
392 }
393 for (i=0; i<MAX_SETUP_STRINGS; i++)
394 setup_used[i] = 0;
395}
396
397
398
399
400
401static int check_setup_strings(char *key, int *flags, int *val, char *buf)
402{
403int x;
404char *cp;
405
406 for (x=0; x<MAX_SETUP_STRINGS; x++) {
407 if (setup_used[x])
408 continue;
409 if (!strncmp(setup_strings[x], key, strlen(key)))
410 break;
411 if (!strncmp(setup_strings[x], "next", strlen("next")))
412 return 0;
413 }
414 if (x == MAX_SETUP_STRINGS)
415 return 0;
416 setup_used[x] = 1;
417 cp = setup_strings[x] + strlen(key);
418 *val = -1;
419 if (*cp != ':')
420 return ++x;
421 cp++;
422 if ((*cp >= '0') && (*cp <= '9')) {
423 *val = simple_strtoul(cp,NULL,0);
424 }
425 return ++x;
426}
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586#define ROUNDUP(adr,type) \
587 ((void *) (((long) (adr) + sizeof(type) - 1) & ~(sizeof(type) - 1)))
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602static inline struct NCR53c7x0_cmd *
603issue_to_cmd (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
604 u32 *issue)
605{
606 return (issue[0] != hostdata->NOP_insn) ?
607
608
609
610
611
612
613
614
615
616
617
618
619 (struct NCR53c7x0_cmd *) ((char *) bus_to_virt (issue[1]) -
620 (hostdata->E_dsa_code_begin - hostdata->E_dsa_code_template) -
621 offsetof(struct NCR53c7x0_cmd, dsa))
622
623 : NULL;
624}
625
626
627
628
629
630
631
632
633
634static const unsigned char sdtr_message[] = {
635#ifdef CONFIG_SCSI_NCR53C7xx_FAST
636 EXTENDED_MESSAGE, 3 , EXTENDED_SDTR, 25 , 8
637#else
638 EXTENDED_MESSAGE, 3 , EXTENDED_SDTR, 50 , 8
639#endif
640};
641
642
643
644static const unsigned char async_message[] = {
645 EXTENDED_MESSAGE, 3 , EXTENDED_SDTR, 0, 0
646};
647
648
649
650static const unsigned char wdtr_message[] = {
651 EXTENDED_MESSAGE, 2 , EXTENDED_WDTR, 1
652};
653
654#if 0
655
656
657
658
659
660
661
662
663
664
665
666static struct Scsi_Host *
667find_host (int host) {
668 struct Scsi_Host *h;
669 for (h = first_host; h && h->host_no != host; h = h->next);
670 if (!h) {
671 printk (KERN_ALERT "scsi%d not found\n", host);
672 return NULL;
673 } else if (h->hostt != the_template) {
674 printk (KERN_ALERT "scsi%d is not a NCR board\n", host);
675 return NULL;
676 }
677 return h;
678}
679
680#if 0
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695static int
696request_synchronous (int host, int target) {
697 struct Scsi_Host *h;
698 struct NCR53c7x0_hostdata *hostdata;
699 unsigned long flags;
700 if (target < 0) {
701 printk (KERN_ALERT "target %d is bogus\n", target);
702 return -1;
703 }
704 if (!(h = find_host (host)))
705 return -1;
706 else if (h->this_id == target) {
707 printk (KERN_ALERT "target %d is host ID\n", target);
708 return -1;
709 }
710 else if (target > h->max_id) {
711 printk (KERN_ALERT "target %d exceeds maximum of %d\n", target,
712 h->max_id);
713 return -1;
714 }
715 hostdata = (struct NCR53c7x0_hostdata *)h->hostdata[0];
716
717 local_irq_save(flags);
718 if (hostdata->initiate_sdtr & (1 << target)) {
719 local_irq_restore(flags);
720 printk (KERN_ALERT "target %d already doing SDTR\n", target);
721 return -1;
722 }
723 hostdata->initiate_sdtr |= (1 << target);
724 local_irq_restore(flags);
725 return 0;
726}
727#endif
728
729
730
731
732
733
734
735
736
737
738
739
740
741static int
742request_disconnect (int host, int on_or_off) {
743 struct Scsi_Host *h;
744 struct NCR53c7x0_hostdata *hostdata;
745 if (!(h = find_host (host)))
746 return -1;
747 hostdata = (struct NCR53c7x0_hostdata *) h->hostdata[0];
748 if (on_or_off)
749 hostdata->options |= OPTION_DISCONNECT;
750 else
751 hostdata->options &= ~OPTION_DISCONNECT;
752 return 0;
753}
754#endif
755
756
757
758
759
760
761
762
763
764
765static void
766NCR53c7x0_driver_init (struct Scsi_Host *host) {
767 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
768 host->hostdata[0];
769 int i, j;
770 u32 *ncrcurrent;
771
772 for (i = 0; i < 16; ++i) {
773 hostdata->request_sense[i] = 0;
774 for (j = 0; j < 8; ++j)
775 hostdata->busy[i][j] = 0;
776 set_synchronous (host, i, 0, hostdata->saved_scntl3, 0);
777 }
778 hostdata->issue_queue = NULL;
779 hostdata->running_list = hostdata->finished_queue =
780 hostdata->ncrcurrent = NULL;
781 for (i = 0, ncrcurrent = (u32 *) hostdata->schedule;
782 i < host->can_queue; ++i, ncrcurrent += 2) {
783 ncrcurrent[0] = hostdata->NOP_insn;
784 ncrcurrent[1] = 0xdeadbeef;
785 }
786 ncrcurrent[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) | DBC_TCI_TRUE;
787 ncrcurrent[1] = (u32) virt_to_bus (hostdata->script) +
788 hostdata->E_wait_reselect;
789 hostdata->reconnect_dsa_head = 0;
790 hostdata->addr_reconnect_dsa_head = (u32)
791 virt_to_bus((void *) &(hostdata->reconnect_dsa_head));
792 hostdata->expecting_iid = 0;
793 hostdata->expecting_sto = 0;
794 if (hostdata->options & OPTION_ALWAYS_SYNCHRONOUS)
795 hostdata->initiate_sdtr = 0xffff;
796 else
797 hostdata->initiate_sdtr = 0;
798 hostdata->talked_to = 0;
799 hostdata->idle = 1;
800}
801
802
803
804
805
806
807
808
809
810
811
812static int
813clock_to_ccf_710 (int clock) {
814 if (clock <= 16666666)
815 return -1;
816 if (clock <= 25000000)
817 return 2;
818 else if (clock <= 37500000)
819 return 1;
820 else if (clock <= 50000000)
821 return 0;
822 else if (clock <= 66000000)
823 return 3;
824 else
825 return -1;
826}
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841int
842NCR53c7x0_init (struct Scsi_Host *host) {
843 NCR53c7x0_local_declare();
844 int i, ccf;
845 unsigned char revision;
846 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
847 host->hostdata[0];
848
849
850
851
852
853
854
855 int val, flags;
856 char buf[32];
857 int expected_id = -1;
858 int expected_clock = -1;
859 int uninitialized = 0;
860#ifdef NO_IO_SPACE
861 int expected_mapping = OPTION_MEMORY_MAPPED;
862#else
863 int expected_mapping = OPTION_IO_MAPPED;
864#endif
865 for (i=0;i<7;i++)
866 hostdata->valid_ids[i] = 1;
867
868
869 if (check_setup_strings("noasync",&flags,&val,buf))
870 {
871 hostdata->options |= OPTION_NO_ASYNC;
872 hostdata->options &= ~(OPTION_SYNCHRONOUS | OPTION_ALWAYS_SYNCHRONOUS);
873 }
874
875 if (check_setup_strings("nosync",&flags,&val,buf))
876 {
877 hostdata->options &= ~(OPTION_SYNCHRONOUS | OPTION_ALWAYS_SYNCHRONOUS);
878 }
879
880 if (check_setup_strings("nodisconnect",&flags,&val,buf))
881 hostdata->options &= ~OPTION_DISCONNECT;
882
883 if (check_setup_strings("validids",&flags,&val,buf))
884 {
885 for (i=0;i<7;i++)
886 hostdata->valid_ids[i] = val & (1<<i);
887 }
888
889 if ((i = check_setup_strings("next",&flags,&val,buf)))
890 {
891 while (i)
892 setup_used[--i] = 1;
893 }
894
895 if (check_setup_strings("opthi",&flags,&val,buf))
896 hostdata->options = (long long)val << 32;
897 if (check_setup_strings("optlo",&flags,&val,buf))
898 hostdata->options |= val;
899
900 NCR53c7x0_local_setup(host);
901 switch (hostdata->chip) {
902 case 710:
903 case 770:
904 hostdata->dstat_sir_intr = NCR53c7x0_dstat_sir_intr;
905 hostdata->init_save_regs = NULL;
906 hostdata->dsa_fixup = NCR53c7xx_dsa_fixup;
907 hostdata->init_fixup = NCR53c7x0_init_fixup;
908 hostdata->soft_reset = NCR53c7x0_soft_reset;
909 hostdata->run_tests = NCR53c7xx_run_tests;
910 expected_clock = hostdata->scsi_clock;
911 expected_id = 7;
912 break;
913 default:
914 printk ("scsi%d : chip type of %d is not supported yet, detaching.\n",
915 host->host_no, hostdata->chip);
916 scsi_unregister (host);
917 return -1;
918 }
919
920
921 hostdata->NCR53c7xx_zero = 0;
922 hostdata->NCR53c7xx_msg_reject = MESSAGE_REJECT;
923 hostdata->NCR53c7xx_msg_abort = ABORT;
924 hostdata->NCR53c7xx_msg_nop = NOP;
925 hostdata->NOP_insn = (DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24;
926 if (expected_mapping == -1 ||
927 (hostdata->options & (OPTION_MEMORY_MAPPED)) !=
928 (expected_mapping & OPTION_MEMORY_MAPPED))
929 printk ("scsi%d : using %s mapped access\n", host->host_no,
930 (hostdata->options & OPTION_MEMORY_MAPPED) ? "memory" :
931 "io");
932
933 hostdata->dmode = (hostdata->chip == 700 || hostdata->chip == 70066) ?
934 DMODE_REG_00 : DMODE_REG_10;
935 hostdata->istat = ((hostdata->chip / 100) == 8) ?
936 ISTAT_REG_800 : ISTAT_REG_700;
937
938
939
940
941 NCR53c7x0_write8 (DCNTL_REG, DCNTL_10_EA|DCNTL_10_COM);
942
943
944
945
946 ncr_halt(host);
947
948
949
950
951
952
953
954
955
956
957#if 0
958
959 tmp = hostdata->this_id_mask = NCR53c7x0_read8(SCID_REG);
960 for (host->this_id = 0; tmp != 1; tmp >>=1, ++host->this_id);
961#else
962 host->this_id = 7;
963#endif
964
965
966
967
968
969
970 if (!host->this_id) {
971 printk("scsi%d : initiator ID was %d, changing to 7\n",
972 host->host_no, host->this_id);
973 host->this_id = 7;
974 hostdata->this_id_mask = 1 << 7;
975 uninitialized = 1;
976 };
977
978 if (expected_id == -1 || host->this_id != expected_id)
979 printk("scsi%d : using initiator ID %d\n", host->host_no,
980 host->this_id);
981
982
983
984
985
986
987
988
989
990
991
992 hostdata->saved_ctest7 = NCR53c7x0_read8(CTEST7_REG) & CTEST7_SAVE;
993 revision = (NCR53c7x0_read8(CTEST8_REG) & 0xF0) >> 4;
994 switch (revision) {
995 case 1: revision = 0; break;
996 case 2: revision = 1; break;
997 case 4: revision = 2; break;
998 case 8: revision = 3; break;
999 default: revision = 255; break;
1000 }
1001 printk("scsi%d: Revision 0x%x\n",host->host_no,revision);
1002
1003 if ((revision == 0 || revision == 255) && (hostdata->options & (OPTION_SYNCHRONOUS|OPTION_DISCONNECT|OPTION_ALWAYS_SYNCHRONOUS)))
1004 {
1005 printk ("scsi%d: Disabling sync working and disconnect/reselect\n",
1006 host->host_no);
1007 hostdata->options &= ~(OPTION_SYNCHRONOUS|OPTION_DISCONNECT|OPTION_ALWAYS_SYNCHRONOUS);
1008 }
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018 hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG);
1019
1020
1021
1022
1023
1024
1025
1026 hostdata->saved_dmode = NCR53c7x0_read8(hostdata->dmode);
1027
1028
1029
1030
1031
1032
1033 ccf = clock_to_ccf_710 (expected_clock);
1034
1035 for (i = 0; i < 16; ++i)
1036 hostdata->cmd_allocated[i] = 0;
1037
1038 if (hostdata->init_save_regs)
1039 hostdata->init_save_regs (host);
1040 if (hostdata->init_fixup)
1041 hostdata->init_fixup (host);
1042
1043 if (!the_template) {
1044 the_template = host->hostt;
1045 first_host = host;
1046 }
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058 hostdata->soft_reset (host);
1059
1060#if 1
1061 hostdata->debug_count_limit = -1;
1062#else
1063 hostdata->debug_count_limit = 1;
1064#endif
1065 hostdata->intrs = -1;
1066 hostdata->resets = -1;
1067 memcpy ((void *) hostdata->synchronous_want, (void *) sdtr_message,
1068 sizeof (hostdata->synchronous_want));
1069
1070 NCR53c7x0_driver_init (host);
1071
1072 if (request_irq(host->irq, NCR53c7x0_intr, SA_SHIRQ, "53c7xx", host))
1073 {
1074 printk("scsi%d : IRQ%d not free, detaching\n",
1075 host->host_no, host->irq);
1076 goto err_unregister;
1077 }
1078
1079 if ((hostdata->run_tests && hostdata->run_tests(host) == -1) ||
1080 (hostdata->options & OPTION_DEBUG_TESTS_ONLY)) {
1081
1082 goto err_free_irq;
1083 } else {
1084 if (host->io_port) {
1085 host->n_io_port = 128;
1086 if (!request_region (host->io_port, host->n_io_port, "ncr53c7xx"))
1087 goto err_free_irq;
1088 }
1089 }
1090
1091 if (NCR53c7x0_read8 (SBCL_REG) & SBCL_BSY) {
1092 printk ("scsi%d : bus wedge, doing SCSI reset\n", host->host_no);
1093 hard_reset (host);
1094 }
1095 return 0;
1096
1097 err_free_irq:
1098 free_irq(host->irq, NCR53c7x0_intr);
1099 err_unregister:
1100 scsi_unregister(host);
1101 return -1;
1102}
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119int
1120ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip,
1121 unsigned long base, int io_port, int irq, int dma,
1122 long long options, int clock)
1123{
1124 struct Scsi_Host *instance;
1125 struct NCR53c7x0_hostdata *hostdata;
1126 char chip_str[80];
1127 int script_len = 0, dsa_len = 0, size = 0, max_cmd_size = 0,
1128 schedule_size = 0, ok = 0;
1129 void *tmp;
1130 unsigned long page;
1131
1132 switch (chip) {
1133 case 710:
1134 case 770:
1135 schedule_size = (tpnt->can_queue + 1) * 8 ;
1136 script_len = NCR53c7xx_script_len;
1137 dsa_len = NCR53c7xx_dsa_len;
1138 options |= OPTION_INTFLY;
1139 sprintf (chip_str, "NCR53c%d", chip);
1140 break;
1141 default:
1142 printk("scsi-ncr53c7xx : unsupported SCSI chip %d\n", chip);
1143 return -1;
1144 }
1145
1146 printk("scsi-ncr53c7xx : %s at memory 0x%lx, io 0x%x, irq %d",
1147 chip_str, base, io_port, irq);
1148 if (dma == DMA_NONE)
1149 printk("\n");
1150 else
1151 printk(", dma %d\n", dma);
1152
1153 if (options & OPTION_DEBUG_PROBE_ONLY) {
1154 printk ("scsi-ncr53c7xx : probe only enabled, aborting initialization\n");
1155 return -1;
1156 }
1157
1158 max_cmd_size = sizeof(struct NCR53c7x0_cmd) + dsa_len +
1159
1160 2 *
1161 ( 2 *
1162 tpnt->sg_tablesize +
1163 3
1164 ) *
1165 8 ;
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188 size = sizeof(struct NCR53c7x0_hostdata) + script_len +
1189
1190
1191
1192
1193
1194
1195 (sizeof(void *) - sizeof(u32)) + max_cmd_size + schedule_size;
1196
1197 page = __get_free_pages(GFP_ATOMIC,1);
1198 if(page==0)
1199 {
1200 printk(KERN_ERR "53c7xx: out of memory.\n");
1201 return -ENOMEM;
1202 }
1203#ifdef FORCE_DSA_ALIGNMENT
1204
1205
1206
1207
1208 size += 256;
1209#endif
1210
1211 if (size > 8192) {
1212 printk(KERN_ERR "53c7xx: hostdata > 8K\n");
1213 return -1;
1214 }
1215
1216 instance = scsi_register (tpnt, 4);
1217 if (!instance)
1218 {
1219 free_page(page);
1220 return -1;
1221 }
1222 instance->hostdata[0] = page;
1223 memset((void *)instance->hostdata[0], 0, 8192);
1224 cache_push(virt_to_phys((void *)(instance->hostdata[0])), 8192);
1225 cache_clear(virt_to_phys((void *)(instance->hostdata[0])), 8192);
1226 kernel_set_cachemode((void *)instance->hostdata[0], 8192, IOMAP_NOCACHE_SER);
1227
1228
1229
1230
1231
1232 hostdata = (struct NCR53c7x0_hostdata *)instance->hostdata[0];
1233 hostdata->size = size;
1234 hostdata->script_count = script_len / sizeof(u32);
1235 hostdata->board = board;
1236 hostdata->chip = chip;
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252 if (base) {
1253 instance->base = base;
1254
1255 if (!(options & OPTION_IO_MAPPED)) {
1256 options |= OPTION_MEMORY_MAPPED;
1257 ok = 1;
1258 }
1259 } else {
1260 options &= ~OPTION_MEMORY_MAPPED;
1261 }
1262
1263 if (io_port) {
1264 instance->io_port = io_port;
1265 options |= OPTION_IO_MAPPED;
1266 ok = 1;
1267 } else {
1268 options &= ~OPTION_IO_MAPPED;
1269 }
1270
1271 if (!ok) {
1272 printk ("scsi%d : not initializing, no I/O or memory mapping known \n",
1273 instance->host_no);
1274 scsi_unregister (instance);
1275 return -1;
1276 }
1277 instance->irq = irq;
1278 instance->dma_channel = dma;
1279
1280 hostdata->options = options;
1281 hostdata->dsa_len = dsa_len;
1282 hostdata->max_cmd_size = max_cmd_size;
1283 hostdata->num_cmds = 1;
1284 hostdata->scsi_clock = clock;
1285
1286 tmp = (hostdata->script + hostdata->script_count);
1287#ifdef FORCE_DSA_ALIGNMENT
1288 {
1289 void *t = ROUNDUP(tmp, void *);
1290 if (((u32)t & 0xff) > CmdPageStart)
1291 t = (void *)((u32)t + 255);
1292 t = (void *)(((u32)t & ~0xff) + CmdPageStart);
1293 hostdata->free = t;
1294#if 0
1295 printk ("scsi: Registered size increased by 256 to %d\n", size);
1296 printk ("scsi: CmdPageStart = 0x%02x\n", CmdPageStart);
1297 printk ("scsi: tmp = 0x%08x, hostdata->free set to 0x%08x\n",
1298 (u32)tmp, (u32)t);
1299#endif
1300 }
1301#else
1302 hostdata->free = ROUNDUP(tmp, void *);
1303#endif
1304 hostdata->free->real = tmp;
1305 hostdata->free->size = max_cmd_size;
1306 hostdata->free->free = NULL;
1307 hostdata->free->next = NULL;
1308 hostdata->extra_allocate = 0;
1309
1310
1311 hostdata->schedule = (chip == 700 || chip == 70066) ?
1312 NULL : (u32 *) ((char *)hostdata->free + max_cmd_size);
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323 if (track_events)
1324 hostdata->events = (struct NCR53c7x0_event *) (track_events ?
1325 vmalloc (sizeof (struct NCR53c7x0_event) * track_events) : NULL);
1326 else
1327 hostdata->events = NULL;
1328
1329 if (hostdata->events) {
1330 memset ((void *) hostdata->events, 0, sizeof(struct NCR53c7x0_event) *
1331 track_events);
1332 hostdata->event_size = track_events;
1333 hostdata->event_index = 0;
1334 } else
1335 hostdata->event_size = 0;
1336
1337 return NCR53c7x0_init(instance);
1338}
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350static void
1351NCR53c7x0_init_fixup (struct Scsi_Host *host) {
1352 NCR53c7x0_local_declare();
1353 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1354 host->hostdata[0];
1355 unsigned char tmp;
1356 int i, ncr_to_memory, memory_to_ncr;
1357 u32 base;
1358 NCR53c7x0_local_setup(host);
1359
1360
1361
1362
1363 memcpy ((void *) hostdata->script, (void *) SCRIPT,
1364 sizeof(SCRIPT));
1365
1366 for (i = 0; i < PATCHES; ++i)
1367 hostdata->script[LABELPATCHES[i]] +=
1368 virt_to_bus(hostdata->script);
1369
1370
1371 patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_abort,
1372 virt_to_bus(&(hostdata->NCR53c7xx_msg_abort)));
1373 patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_reject,
1374 virt_to_bus(&(hostdata->NCR53c7xx_msg_reject)));
1375 patch_abs_32 (hostdata->script, 0, NCR53c7xx_zero,
1376 virt_to_bus(&(hostdata->NCR53c7xx_zero)));
1377 patch_abs_32 (hostdata->script, 0, NCR53c7xx_sink,
1378 virt_to_bus(&(hostdata->NCR53c7xx_sink)));
1379 patch_abs_32 (hostdata->script, 0, NOP_insn,
1380 virt_to_bus(&(hostdata->NOP_insn)));
1381 patch_abs_32 (hostdata->script, 0, schedule,
1382 virt_to_bus((void *) hostdata->schedule));
1383
1384
1385 for (i = 0; i < EXTERNAL_PATCHES_LEN; ++i)
1386 hostdata->script[EXTERNAL_PATCHES[i].offset] +=
1387 virt_to_bus(EXTERNAL_PATCHES[i].address);
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398 patch_abs_rwri_data (hostdata->script, 0, dsa_save_data_pointer,
1399 Ent_dsa_code_save_data_pointer - Ent_dsa_zero);
1400 patch_abs_rwri_data (hostdata->script, 0, dsa_restore_pointers,
1401 Ent_dsa_code_restore_pointers - Ent_dsa_zero);
1402 patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect,
1403 Ent_dsa_code_check_reselect - Ent_dsa_zero);
1404
1405
1406
1407
1408
1409
1410
1411#if defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000)
1412
1413 tmp = DMODE_10_BL_8 | DMODE_10_FC2;
1414#else
1415 tmp = NCR53c7x0_read8(DMODE_REG_10);
1416 tmp &= (DMODE_BL_MASK | DMODE_10_FC2 | DMODE_10_FC1 | DMODE_710_PD |
1417 DMODE_710_UO);
1418#endif
1419
1420 if (!(hostdata->options & OPTION_MEMORY_MAPPED)) {
1421 base = (u32) host->io_port;
1422 memory_to_ncr = tmp|DMODE_800_DIOM;
1423 ncr_to_memory = tmp|DMODE_800_SIOM;
1424 } else {
1425 base = virt_to_bus((void *)host->base);
1426 memory_to_ncr = ncr_to_memory = tmp;
1427 }
1428
1429
1430 patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800);
1431 patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG);
1432 patch_abs_32 (hostdata->script, 0, addr_dsa, base + DSA_REG);
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443 patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_memory, tmp);
1444 patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_ncr, memory_to_ncr);
1445 patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory);
1446
1447 patch_abs_32 (hostdata->script, 0, msg_buf,
1448 virt_to_bus((void *)&(hostdata->msg_buf)));
1449 patch_abs_32 (hostdata->script, 0, reconnect_dsa_head,
1450 virt_to_bus((void *)&(hostdata->reconnect_dsa_head)));
1451 patch_abs_32 (hostdata->script, 0, addr_reconnect_dsa_head,
1452 virt_to_bus((void *)&(hostdata->addr_reconnect_dsa_head)));
1453 patch_abs_32 (hostdata->script, 0, reselected_identify,
1454 virt_to_bus((void *)&(hostdata->reselected_identify)));
1455
1456#if 0
1457 patch_abs_32 (hostdata->script, 0, reselected_tag,
1458 virt_to_bus((void *)&(hostdata->reselected_tag)));
1459#endif
1460
1461 patch_abs_32 (hostdata->script, 0, test_dest,
1462 virt_to_bus((void*)&hostdata->test_dest));
1463 patch_abs_32 (hostdata->script, 0, test_src,
1464 virt_to_bus(&hostdata->test_source));
1465 patch_abs_32 (hostdata->script, 0, saved_dsa,
1466 virt_to_bus((void *)&hostdata->saved2_dsa));
1467 patch_abs_32 (hostdata->script, 0, emulfly,
1468 virt_to_bus((void *)&hostdata->emulated_intfly));
1469
1470 patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect,
1471 (unsigned char)(Ent_dsa_code_check_reselect - Ent_dsa_zero));
1472
1473
1474
1475#ifdef A_int_EVENT_SELECT
1476 patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT, (u32) EVENT_SELECT);
1477#endif
1478#ifdef A_int_EVENT_DISCONNECT
1479 patch_abs_32 (hostdata->script, 0, int_EVENT_DISCONNECT, (u32) EVENT_DISCONNECT);
1480#endif
1481#ifdef A_int_EVENT_RESELECT
1482 patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT, (u32) EVENT_RESELECT);
1483#endif
1484#ifdef A_int_EVENT_COMPLETE
1485 patch_abs_32 (hostdata->script, 0, int_EVENT_COMPLETE, (u32) EVENT_COMPLETE);
1486#endif
1487#ifdef A_int_EVENT_IDLE
1488 patch_abs_32 (hostdata->script, 0, int_EVENT_IDLE, (u32) EVENT_IDLE);
1489#endif
1490#ifdef A_int_EVENT_SELECT_FAILED
1491 patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT_FAILED,
1492 (u32) EVENT_SELECT_FAILED);
1493#endif
1494#ifdef A_int_EVENT_BEFORE_SELECT
1495 patch_abs_32 (hostdata->script, 0, int_EVENT_BEFORE_SELECT,
1496 (u32) EVENT_BEFORE_SELECT);
1497#endif
1498#ifdef A_int_EVENT_RESELECT_FAILED
1499 patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT_FAILED,
1500 (u32) EVENT_RESELECT_FAILED);
1501#endif
1502
1503
1504
1505
1506
1507
1508 hostdata->E_accept_message = Ent_accept_message;
1509 hostdata->E_command_complete = Ent_command_complete;
1510 hostdata->E_cmdout_cmdout = Ent_cmdout_cmdout;
1511 hostdata->E_data_transfer = Ent_data_transfer;
1512 hostdata->E_debug_break = Ent_debug_break;
1513 hostdata->E_dsa_code_template = Ent_dsa_code_template;
1514 hostdata->E_dsa_code_template_end = Ent_dsa_code_template_end;
1515 hostdata->E_end_data_transfer = Ent_end_data_transfer;
1516 hostdata->E_initiator_abort = Ent_initiator_abort;
1517 hostdata->E_msg_in = Ent_msg_in;
1518 hostdata->E_other_transfer = Ent_other_transfer;
1519 hostdata->E_other_in = Ent_other_in;
1520 hostdata->E_other_out = Ent_other_out;
1521 hostdata->E_reject_message = Ent_reject_message;
1522 hostdata->E_respond_message = Ent_respond_message;
1523 hostdata->E_select = Ent_select;
1524 hostdata->E_select_msgout = Ent_select_msgout;
1525 hostdata->E_target_abort = Ent_target_abort;
1526#ifdef Ent_test_0
1527 hostdata->E_test_0 = Ent_test_0;
1528#endif
1529 hostdata->E_test_1 = Ent_test_1;
1530 hostdata->E_test_2 = Ent_test_2;
1531#ifdef Ent_test_3
1532 hostdata->E_test_3 = Ent_test_3;
1533#endif
1534 hostdata->E_wait_reselect = Ent_wait_reselect;
1535 hostdata->E_dsa_code_begin = Ent_dsa_code_begin;
1536
1537 hostdata->dsa_cmdout = A_dsa_cmdout;
1538 hostdata->dsa_cmnd = A_dsa_cmnd;
1539 hostdata->dsa_datain = A_dsa_datain;
1540 hostdata->dsa_dataout = A_dsa_dataout;
1541 hostdata->dsa_end = A_dsa_end;
1542 hostdata->dsa_msgin = A_dsa_msgin;
1543 hostdata->dsa_msgout = A_dsa_msgout;
1544 hostdata->dsa_msgout_other = A_dsa_msgout_other;
1545 hostdata->dsa_next = A_dsa_next;
1546 hostdata->dsa_select = A_dsa_select;
1547 hostdata->dsa_start = Ent_dsa_code_template - Ent_dsa_zero;
1548 hostdata->dsa_status = A_dsa_status;
1549 hostdata->dsa_jump_dest = Ent_dsa_code_fix_jump - Ent_dsa_zero +
1550 8 ;
1551
1552
1553 if (A_dsa_fields_start != Ent_dsa_code_template_end -
1554 Ent_dsa_zero)
1555 printk("scsi%d : NCR dsa_fields start is %d not %d\n",
1556 host->host_no, A_dsa_fields_start, Ent_dsa_code_template_end -
1557 Ent_dsa_zero);
1558
1559 printk("scsi%d : NCR code relocated to 0x%lx (virt 0x%p)\n", host->host_no,
1560 virt_to_bus(hostdata->script), hostdata->script);
1561}
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578static int
1579NCR53c7xx_run_tests (struct Scsi_Host *host) {
1580 NCR53c7x0_local_declare();
1581 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1582 host->hostdata[0];
1583 unsigned long timeout;
1584 u32 start;
1585 int failed, i;
1586 unsigned long flags;
1587 NCR53c7x0_local_setup(host);
1588
1589
1590
1591 local_irq_save(flags);
1592 if (!hostdata->idle) {
1593 printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
1594 local_irq_restore(flags);
1595 return -1;
1596 }
1597
1598
1599
1600
1601
1602
1603 if ((hostdata->options & OPTION_DEBUG_TEST1) &&
1604 hostdata->state != STATE_DISABLED) {
1605 hostdata->idle = 0;
1606 hostdata->test_running = 1;
1607 hostdata->test_completed = -1;
1608 hostdata->test_dest = 0;
1609 hostdata->test_source = 0xdeadbeef;
1610 start = virt_to_bus (hostdata->script) + hostdata->E_test_1;
1611 hostdata->state = STATE_RUNNING;
1612 printk ("scsi%d : test 1", host->host_no);
1613 NCR53c7x0_write32 (DSP_REG, start);
1614 if (hostdata->options & OPTION_DEBUG_TRACE)
1615 NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl | DCNTL_SSM |
1616 DCNTL_STD);
1617 printk (" started\n");
1618 local_irq_restore(flags);
1619
1620
1621
1622
1623
1624
1625
1626
1627 timeout = jiffies + 5 * HZ / 10;
1628 while ((hostdata->test_completed == -1) && time_before(jiffies, timeout))
1629 barrier();
1630
1631 failed = 1;
1632 if (hostdata->test_completed == -1)
1633 printk ("scsi%d : driver test 1 timed out%s\n",host->host_no ,
1634 (hostdata->test_dest == 0xdeadbeef) ?
1635 " due to lost interrupt.\n"
1636 " Please verify that the correct IRQ is being used for your board,\n"
1637 : "");
1638 else if (hostdata->test_completed != 1)
1639 printk ("scsi%d : test 1 bad interrupt value (%d)\n",
1640 host->host_no, hostdata->test_completed);
1641 else
1642 failed = (hostdata->test_dest != 0xdeadbeef);
1643
1644 if (hostdata->test_dest != 0xdeadbeef) {
1645 printk ("scsi%d : driver test 1 read 0x%x instead of 0xdeadbeef indicating a\n"
1646 " probable cache invalidation problem. Please configure caching\n"
1647 " as write-through or disabled\n",
1648 host->host_no, hostdata->test_dest);
1649 }
1650
1651 if (failed) {
1652 printk ("scsi%d : DSP = 0x%p (script at 0x%p, start at 0x%x)\n",
1653 host->host_no, bus_to_virt(NCR53c7x0_read32(DSP_REG)),
1654 hostdata->script, start);
1655 printk ("scsi%d : DSPS = 0x%x\n", host->host_no,
1656 NCR53c7x0_read32(DSPS_REG));
1657 local_irq_restore(flags);
1658 return -1;
1659 }
1660 hostdata->test_running = 0;
1661 }
1662
1663 if ((hostdata->options & OPTION_DEBUG_TEST2) &&
1664 hostdata->state != STATE_DISABLED) {
1665 u32 dsa[48];
1666 unsigned char identify = IDENTIFY(0, 0);
1667 unsigned char cmd[6];
1668 unsigned char data[36];
1669 unsigned char status = 0xff;
1670 unsigned char msg = 0xff;
1671
1672 cmd[0] = INQUIRY;
1673 cmd[1] = cmd[2] = cmd[3] = cmd[5] = 0;
1674 cmd[4] = sizeof(data);
1675
1676 dsa[2] = 1;
1677 dsa[3] = virt_to_bus(&identify);
1678 dsa[4] = 6;
1679 dsa[5] = virt_to_bus(&cmd);
1680 dsa[6] = sizeof(data);
1681 dsa[7] = virt_to_bus(&data);
1682 dsa[8] = 1;
1683 dsa[9] = virt_to_bus(&status);
1684 dsa[10] = 1;
1685 dsa[11] = virt_to_bus(&msg);
1686
1687 for (i = 0; i < 6; ++i) {
1688#ifdef VALID_IDS
1689 if (!hostdata->valid_ids[i])
1690 continue;
1691#endif
1692 local_irq_disable();
1693 if (!hostdata->idle) {
1694 printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
1695 local_irq_restore(flags);
1696 return -1;
1697 }
1698
1699
1700 dsa[0] = (1 << i) << 16;
1701 hostdata->idle = 0;
1702 hostdata->test_running = 2;
1703 hostdata->test_completed = -1;
1704 start = virt_to_bus(hostdata->script) + hostdata->E_test_2;
1705 hostdata->state = STATE_RUNNING;
1706 NCR53c7x0_write32 (DSA_REG, virt_to_bus(dsa));
1707 NCR53c7x0_write32 (DSP_REG, start);
1708 if (hostdata->options & OPTION_DEBUG_TRACE)
1709 NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl |
1710 DCNTL_SSM | DCNTL_STD);
1711 local_irq_restore(flags);
1712
1713 timeout = jiffies + 5 * HZ;
1714 while ((hostdata->test_completed == -1) && time_before(jiffies, timeout))
1715 barrier();
1716
1717 NCR53c7x0_write32 (DSA_REG, 0);
1718
1719 if (hostdata->test_completed == 2) {
1720 data[35] = 0;
1721 printk ("scsi%d : test 2 INQUIRY to target %d, lun 0 : %s\n",
1722 host->host_no, i, data + 8);
1723 printk ("scsi%d : status ", host->host_no);
1724 print_status (status);
1725 printk ("\nscsi%d : message ", host->host_no);
1726 print_msg (&msg);
1727 printk ("\n");
1728 } else if (hostdata->test_completed == 3) {
1729 printk("scsi%d : test 2 no connection with target %d\n",
1730 host->host_no, i);
1731 if (!hostdata->idle) {
1732 printk("scsi%d : not idle\n", host->host_no);
1733 local_irq_restore(flags);
1734 return -1;
1735 }
1736 } else if (hostdata->test_completed == -1) {
1737 printk ("scsi%d : test 2 timed out\n", host->host_no);
1738 local_irq_restore(flags);
1739 return -1;
1740 }
1741 hostdata->test_running = 0;
1742 }
1743 }
1744
1745 local_irq_restore(flags);
1746 return 0;
1747}
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759static void
1760NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
1761 Scsi_Cmnd *c = cmd->cmd;
1762 struct Scsi_Host *host = c->device->host;
1763 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1764 host->hostdata[0];
1765 int i;
1766
1767 memcpy (cmd->dsa, hostdata->script + (hostdata->E_dsa_code_template / 4),
1768 hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template);
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786 patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
1787 dsa_temp_lun, c->device->lun);
1788 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
1789 dsa_temp_addr_next, virt_to_bus(&cmd->dsa_next_addr));
1790 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
1791 dsa_temp_next, virt_to_bus(cmd->dsa) + Ent_dsa_zero -
1792 Ent_dsa_code_template + A_dsa_next);
1793 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
1794 dsa_temp_sync, virt_to_bus((void *)hostdata->sync[c->device->id].script));
1795 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
1796 dsa_sscf_710, virt_to_bus((void *)&hostdata->sync[c->device->id].sscf_710));
1797 patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
1798 dsa_temp_target, 1 << c->device->id);
1799
1800 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
1801 dsa_temp_addr_saved_pointer, virt_to_bus(&cmd->saved_data_pointer));
1802 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
1803 dsa_temp_addr_saved_residual, virt_to_bus(&cmd->saved_residual));
1804 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
1805 dsa_temp_addr_residual, virt_to_bus(&cmd->residual));
1806
1807
1808
1809 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
1810 dsa_temp_addr_dsa_value, virt_to_bus(&cmd->dsa_addr));
1811}
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823static volatile int process_issue_queue_running = 0;
1824
1825static __inline__ void
1826run_process_issue_queue(void) {
1827 unsigned long flags;
1828 local_irq_save(flags);
1829 if (!process_issue_queue_running) {
1830 process_issue_queue_running = 1;
1831 process_issue_queue(flags);
1832
1833
1834
1835
1836
1837 }
1838 local_irq_restore(flags);
1839}
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856static void
1857abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
1858 Scsi_Cmnd *c = cmd->cmd;
1859 struct Scsi_Host *host = c->device->host;
1860 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1861 host->hostdata[0];
1862 unsigned long flags;
1863 int left, found;
1864 volatile struct NCR53c7x0_cmd * linux_search;
1865 volatile struct NCR53c7x0_cmd * volatile *linux_prev;
1866 volatile u32 *ncr_prev, *ncrcurrent, ncr_search;
1867
1868#if 0
1869 printk ("scsi%d: abnormal finished\n", host->host_no);
1870#endif
1871
1872 local_irq_save(flags);
1873 found = 0;
1874
1875
1876
1877
1878
1879
1880
1881 for (found = 0, left = host->can_queue, ncrcurrent = hostdata->schedule;
1882 left > 0; --left, ncrcurrent += 2)
1883 {
1884 if (issue_to_cmd (host, hostdata, (u32 *) ncrcurrent) == cmd)
1885 {
1886 ncrcurrent[0] = hostdata->NOP_insn;
1887 ncrcurrent[1] = 0xdeadbeef;
1888 ++found;
1889 break;
1890 }
1891 }
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901 for (left = host->can_queue,
1902 ncr_search = hostdata->reconnect_dsa_head,
1903 ncr_prev = &hostdata->reconnect_dsa_head;
1904 left >= 0 && ncr_search &&
1905 ((char*)bus_to_virt(ncr_search) + hostdata->dsa_start)
1906 != (char *) cmd->dsa;
1907 ncr_prev = (u32*) ((char*)bus_to_virt(ncr_search) +
1908 hostdata->dsa_next), ncr_search = *ncr_prev, --left);
1909
1910 if (left < 0)
1911 printk("scsi%d: loop detected in ncr reconncect list\n",
1912 host->host_no);
1913 else if (ncr_search) {
1914 if (found)
1915 printk("scsi%d: scsi %ld in ncr issue array and reconnect lists\n",
1916 host->host_no, c->pid);
1917 else {
1918 volatile u32 * next = (u32 *)
1919 ((char *)bus_to_virt(ncr_search) + hostdata->dsa_next);
1920 *ncr_prev = *next;
1921
1922 found = 1;
1923 }
1924 }
1925
1926
1927
1928
1929
1930
1931
1932 for (left = host->can_queue, linux_search = hostdata->running_list,
1933 linux_prev = &hostdata->running_list;
1934 left >= 0 && linux_search && linux_search != cmd;
1935 linux_prev = &(linux_search->next),
1936 linux_search = linux_search->next, --left);
1937
1938 if (left < 0)
1939 printk ("scsi%d: loop detected in host running list for scsi pid %ld\n",
1940 host->host_no, c->pid);
1941 else if (linux_search) {
1942 *linux_prev = linux_search->next;
1943 --hostdata->busy[c->device->id][c->device->lun];
1944 }
1945
1946
1947 cmd->next = hostdata->free;
1948 hostdata->free = cmd;
1949 c->host_scribble = NULL;
1950
1951
1952 c->result = result;
1953 c->scsi_done(c);
1954
1955 local_irq_restore(flags);
1956 run_process_issue_queue();
1957}
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971static void
1972intr_break (struct Scsi_Host *host, struct
1973 NCR53c7x0_cmd *cmd) {
1974 NCR53c7x0_local_declare();
1975 struct NCR53c7x0_break *bp;
1976#if 0
1977 Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
1978#endif
1979 u32 *dsp;
1980 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1981 host->hostdata[0];
1982 unsigned long flags;
1983 NCR53c7x0_local_setup(host);
1984
1985
1986
1987
1988
1989
1990 local_irq_save(flags);
1991 dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
1992 for (bp = hostdata->breakpoints; bp && bp->address != dsp;
1993 bp = bp->next);
1994 if (!bp)
1995 panic("scsi%d : break point interrupt from %p with no breakpoint!",
1996 host->host_no, dsp);
1997
1998
1999
2000
2001
2002
2003
2004 NCR53c7x0_write8 (hostdata->dmode,
2005 NCR53c7x0_read8(hostdata->dmode)|DMODE_MAN);
2006
2007
2008
2009
2010
2011
2012 local_irq_restore(flags);
2013}
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025static void
2026print_synchronous (const char *prefix, const unsigned char *msg) {
2027 if (msg[4]) {
2028 int Hz = 1000000000 / (msg[3] * 4);
2029 int integer = Hz / 1000000;
2030 int fraction = (Hz - (integer * 1000000)) / 10000;
2031 printk ("%speriod %dns offset %d %d.%02dMHz %s SCSI%s\n",
2032 prefix, (int) msg[3] * 4, (int) msg[4], integer, fraction,
2033 (((msg[3] * 4) < 200) ? "FAST" : "synchronous"),
2034 (((msg[3] * 4) < 200) ? "-II" : ""));
2035 } else
2036 printk ("%sasynchronous SCSI\n", prefix);
2037}
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055static void
2056set_synchronous (struct Scsi_Host *host, int target, int sxfer, int scntl3,
2057 int now_connected) {
2058 NCR53c7x0_local_declare();
2059 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2060 host->hostdata[0];
2061 u32 *script;
2062 NCR53c7x0_local_setup(host);
2063
2064
2065 sxfer &= 0xff;
2066 scntl3 &= 0xff;
2067
2068 hostdata->sync[target].sxfer_sanity = sxfer;
2069 hostdata->sync[target].scntl3_sanity = scntl3;
2070
2071
2072
2073
2074
2075
2076 if ((hostdata->chip != 700) && (hostdata->chip != 70066)) {
2077 hostdata->sync[target].select_indirect = (1 << target) << 16 |
2078 (sxfer << 8);
2079 hostdata->sync[target].sscf_710 = scntl3;
2080
2081 script = (u32 *) hostdata->sync[target].script;
2082
2083
2084 script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
2085 DCMD_RWRI_OP_MOVE) << 24) |
2086 (SBCL_REG << 16) | (scntl3 << 8);
2087 script[1] = 0;
2088 script += 2;
2089
2090 script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
2091 DCMD_RWRI_OP_MOVE) << 24) |
2092 (SXFER_REG << 16) | (sxfer << 8);
2093 script[1] = 0;
2094 script += 2;
2095
2096#ifdef DEBUG_SYNC_INTR
2097 if (hostdata->options & OPTION_DEBUG_DISCONNECT) {
2098 script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_INT) << 24) | DBC_TCI_TRUE;
2099 script[1] = DEBUG_SYNC_INTR;
2100 script += 2;
2101 }
2102#endif
2103
2104 script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_RETURN) << 24) | DBC_TCI_TRUE;
2105 script[1] = 0;
2106 script += 2;
2107 }
2108
2109 if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS)
2110 printk ("scsi%d : target %d sync parameters are sxfer=0x%x, scntl3=0x%x\n",
2111 host->host_no, target, sxfer, scntl3);
2112
2113 if (now_connected) {
2114 NCR53c7x0_write8(SBCL_REG, scntl3);
2115 NCR53c7x0_write8(SXFER_REG, sxfer);
2116 }
2117}
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131static void
2132asynchronous (struct Scsi_Host *host, int target) {
2133 NCR53c7x0_local_declare();
2134 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2135 host->hostdata[0];
2136 NCR53c7x0_local_setup(host);
2137 set_synchronous (host, target, 0, hostdata->saved_scntl3,
2138 1);
2139 printk ("scsi%d : setting target %d to asynchronous SCSI\n",
2140 host->host_no, target);
2141}
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160static const struct {
2161 int div;
2162 unsigned char scf;
2163 unsigned char tp;
2164} syncs[] = {
2165
2166 { 40, 1, 0}, { 50, 1, 1}, { 60, 1, 2},
2167 { 70, 1, 3}, { 75, 2, 1}, { 80, 1, 4},
2168 { 90, 1, 5}, { 100, 1, 6}, { 105, 2, 3},
2169 { 110, 1, 7}, { 120, 2, 4}, { 135, 2, 5},
2170 { 140, 3, 3}, { 150, 2, 6}, { 160, 3, 4},
2171 { 165, 2, 7}, { 180, 3, 5}, { 200, 3, 6},
2172 { 210, 4, 3}, { 220, 3, 7}, { 240, 4, 4},
2173 { 270, 4, 5}, { 300, 4, 6}, { 330, 4, 7}
2174};
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191static void
2192synchronous (struct Scsi_Host *host, int target, char *msg) {
2193 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2194 host->hostdata[0];
2195 int desire, divisor, i, limit;
2196 unsigned char scntl3, sxfer;
2197
2198 char buf[80];
2199
2200
2201 desire = 1000000000L / (msg[3] * 4);
2202
2203 divisor = (hostdata->scsi_clock * 10) / desire;
2204
2205
2206 if (msg[4] > 8)
2207 msg[4] = 8;
2208
2209 if (hostdata->options & OPTION_DEBUG_SDTR)
2210 printk("scsi%d : optimal synchronous divisor of %d.%01d\n",
2211 host->host_no, divisor / 10, divisor % 10);
2212
2213 limit = (sizeof(syncs) / sizeof(syncs[0]) -1);
2214 for (i = 0; (i < limit) && (divisor > syncs[i].div); ++i);
2215
2216 if (hostdata->options & OPTION_DEBUG_SDTR)
2217 printk("scsi%d : selected synchronous divisor of %d.%01d\n",
2218 host->host_no, syncs[i].div / 10, syncs[i].div % 10);
2219
2220 msg[3] = ((1000000000L / hostdata->scsi_clock) * syncs[i].div / 10 / 4);
2221
2222 if (hostdata->options & OPTION_DEBUG_SDTR)
2223 printk("scsi%d : selected synchronous period of %dns\n", host->host_no,
2224 msg[3] * 4);
2225
2226 scntl3 = syncs[i].scf;
2227 sxfer = (msg[4] << SXFER_MO_SHIFT) | (syncs[i].tp << 4);
2228 if (hostdata->options & OPTION_DEBUG_SDTR)
2229 printk ("scsi%d : sxfer=0x%x scntl3=0x%x\n",
2230 host->host_no, (int) sxfer, (int) scntl3);
2231 set_synchronous (host, target, sxfer, scntl3, 1);
2232 sprintf (buf, "scsi%d : setting target %d to ", host->host_no, target);
2233 print_synchronous (buf, msg);
2234}
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249static int
2250NCR53c7x0_dstat_sir_intr (struct Scsi_Host *host, struct
2251 NCR53c7x0_cmd *cmd) {
2252 NCR53c7x0_local_declare();
2253 int print;
2254 Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
2255 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2256 host->hostdata[0];
2257 u32 dsps,*dsp;
2258
2259 NCR53c7x0_local_setup(host);
2260 dsps = NCR53c7x0_read32(DSPS_REG);
2261 dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
2262
2263
2264
2265#if 0
2266
2267
2268
2269 if (dsps == A_int_norm_emulateintfly && cmd && cmd->result == 2)
2270 dsps = A_int_err_check_condition;
2271#endif
2272
2273 if (hostdata->options & OPTION_DEBUG_INTR)
2274 printk ("scsi%d : DSPS = 0x%x\n", host->host_no, dsps);
2275
2276 switch (dsps) {
2277 case A_int_msg_1:
2278 print = 1;
2279 switch (hostdata->msg_buf[0]) {
2280
2281
2282
2283
2284 case MESSAGE_REJECT:
2285 hostdata->dsp = hostdata->script + hostdata->E_accept_message /
2286 sizeof(u32);
2287 hostdata->dsp_changed = 1;
2288 if (cmd && (cmd->flags & CMD_FLAG_SDTR)) {
2289 printk ("scsi%d : target %d rejected SDTR\n", host->host_no,
2290 c->device->id);
2291 cmd->flags &= ~CMD_FLAG_SDTR;
2292 asynchronous (host, c->device->id);
2293 print = 0;
2294 }
2295 break;
2296 case INITIATE_RECOVERY:
2297 printk ("scsi%d : extended contingent allegiance not supported yet, rejecting\n",
2298 host->host_no);
2299
2300 hostdata->dsp = hostdata->script + hostdata->E_reject_message /
2301 sizeof(u32);
2302 hostdata->dsp_changed = 1;
2303 break;
2304 default:
2305 printk ("scsi%d : unsupported message, rejecting\n",
2306 host->host_no);
2307 hostdata->dsp = hostdata->script + hostdata->E_reject_message /
2308 sizeof(u32);
2309 hostdata->dsp_changed = 1;
2310 }
2311 if (print) {
2312 printk ("scsi%d : received message", host->host_no);
2313 if (c)
2314 printk (" from target %d lun %d ", c->device->id, c->device->lun);
2315 print_msg ((unsigned char *) hostdata->msg_buf);
2316 printk("\n");
2317 }
2318
2319 return SPECIFIC_INT_NOTHING;
2320
2321
2322 case A_int_msg_sdtr:
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332 if (cmd) {
2333 char buf[80];
2334 sprintf (buf, "scsi%d : target %d %s ", host->host_no, c->device->id,
2335 (cmd->flags & CMD_FLAG_SDTR) ? "accepting" : "requesting");
2336 print_synchronous (buf, (unsigned char *) hostdata->msg_buf);
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346 if (cmd->flags & CMD_FLAG_SDTR) {
2347 cmd->flags &= ~CMD_FLAG_SDTR;
2348 if (hostdata->msg_buf[4])
2349 synchronous (host, c->device->id, (unsigned char *)
2350 hostdata->msg_buf);
2351 else
2352 asynchronous (host, c->device->id);
2353 hostdata->dsp = hostdata->script + hostdata->E_accept_message /
2354 sizeof(u32);
2355 hostdata->dsp_changed = 1;
2356 return SPECIFIC_INT_NOTHING;
2357 } else {
2358 if (hostdata->options & OPTION_SYNCHRONOUS) {
2359 cmd->flags |= CMD_FLAG_DID_SDTR;
2360 synchronous (host, c->device->id, (unsigned char *)
2361 hostdata->msg_buf);
2362 } else {
2363 hostdata->msg_buf[4] = 0;
2364 asynchronous (host, c->device->id);
2365 }
2366 patch_dsa_32 (cmd->dsa, dsa_msgout_other, 0, 5);
2367 patch_dsa_32 (cmd->dsa, dsa_msgout_other, 1, (u32)
2368 virt_to_bus ((void *)&hostdata->msg_buf));
2369 hostdata->dsp = hostdata->script +
2370 hostdata->E_respond_message / sizeof(u32);
2371 hostdata->dsp_changed = 1;
2372 }
2373 return SPECIFIC_INT_NOTHING;
2374 }
2375
2376
2377 case A_int_msg_wdtr:
2378 hostdata->dsp = hostdata->script + hostdata->E_reject_message /
2379 sizeof(u32);
2380 hostdata->dsp_changed = 1;
2381 return SPECIFIC_INT_NOTHING;
2382 case A_int_err_unexpected_phase:
2383 if (hostdata->options & OPTION_DEBUG_INTR)
2384 printk ("scsi%d : unexpected phase\n", host->host_no);
2385 return SPECIFIC_INT_ABORT;
2386 case A_int_err_selected:
2387 if ((hostdata->chip / 100) == 8)
2388 printk ("scsi%d : selected by target %d\n", host->host_no,
2389 (int) NCR53c7x0_read8(SDID_REG_800) &7);
2390 else
2391 printk ("scsi%d : selected by target LCRC=0x%02x\n", host->host_no,
2392 (int) NCR53c7x0_read8(LCRC_REG_10));
2393 hostdata->dsp = hostdata->script + hostdata->E_target_abort /
2394 sizeof(u32);
2395 hostdata->dsp_changed = 1;
2396 return SPECIFIC_INT_NOTHING;
2397 case A_int_err_unexpected_reselect:
2398 if ((hostdata->chip / 100) == 8)
2399 printk ("scsi%d : unexpected reselect by target %d lun %d\n",
2400 host->host_no, (int) NCR53c7x0_read8(SDID_REG_800) & 7,
2401 hostdata->reselected_identify & 7);
2402 else
2403 printk ("scsi%d : unexpected reselect LCRC=0x%02x\n", host->host_no,
2404 (int) NCR53c7x0_read8(LCRC_REG_10));
2405 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
2406 sizeof(u32);
2407 hostdata->dsp_changed = 1;
2408 return SPECIFIC_INT_NOTHING;
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418 case A_int_err_check_condition:
2419#if 0
2420 if (hostdata->options & OPTION_DEBUG_INTR)
2421#endif
2422 printk ("scsi%d : CHECK CONDITION\n", host->host_no);
2423 if (!c) {
2424 printk("scsi%d : CHECK CONDITION with no SCSI command\n",
2425 host->host_no);
2426 return SPECIFIC_INT_PANIC;
2427 }
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439 patch_dsa_32 (cmd->dsa, dsa_msgout, 0, 1);
2440
2441
2442
2443
2444
2445
2446 patch_dsa_32 (cmd->dsa, dsa_cmdout, 0, 6);
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459 cmd->cmnd[0] = c->cmnd[0] = REQUEST_SENSE;
2460 cmd->cmnd[0] = c->cmnd[1] &= 0xe0;
2461 cmd->cmnd[0] = c->cmnd[2] = 0;
2462 cmd->cmnd[0] = c->cmnd[3] = 0;
2463 cmd->cmnd[0] = c->cmnd[4] = sizeof(c->sense_buffer);
2464 cmd->cmnd[0] = c->cmnd[5] = 0;
2465
2466
2467
2468
2469
2470
2471
2472 patch_dsa_32 (cmd->dsa, dsa_dataout, 0,
2473 virt_to_bus(hostdata->script) + hostdata->E_other_transfer);
2474 patch_dsa_32 (cmd->dsa, dsa_datain, 0,
2475 virt_to_bus(cmd->data_transfer_start));
2476 cmd->data_transfer_start[0] = (((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I |
2477 DCMD_BMI_IO)) << 24) | sizeof(c->sense_buffer);
2478 cmd->data_transfer_start[1] = (u32) virt_to_bus(c->sense_buffer);
2479
2480 cmd->data_transfer_start[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP)
2481 << 24) | DBC_TCI_TRUE;
2482 cmd->data_transfer_start[3] = (u32) virt_to_bus(hostdata->script) +
2483 hostdata->E_other_transfer;
2484
2485
2486
2487
2488
2489
2490
2491
2492 cmd->result = cmd->cmd->result = 0xffff;
2493
2494
2495
2496
2497 hostdata->dsp = (u32 *) hostdata->script + hostdata->E_select /
2498 sizeof(u32);
2499 hostdata->dsp_changed = 1;
2500 return SPECIFIC_INT_NOTHING;
2501 case A_int_debug_break:
2502 return SPECIFIC_INT_BREAK;
2503 case A_int_norm_aborted:
2504 hostdata->dsp = (u32 *) hostdata->schedule;
2505 hostdata->dsp_changed = 1;
2506 if (cmd)
2507 abnormal_finished (cmd, DID_ERROR << 16);
2508 return SPECIFIC_INT_NOTHING;
2509 case A_int_norm_emulateintfly:
2510 NCR53c7x0_intfly(host);
2511 return SPECIFIC_INT_NOTHING;
2512 case A_int_test_1:
2513 case A_int_test_2:
2514 hostdata->idle = 1;
2515 hostdata->test_completed = (dsps - A_int_test_1) / 0x00010000 + 1;
2516 if (hostdata->options & OPTION_DEBUG_INTR)
2517 printk("scsi%d : test%d complete\n", host->host_no,
2518 hostdata->test_completed);
2519 return SPECIFIC_INT_NOTHING;
2520#ifdef A_int_debug_reselected_ok
2521 case A_int_debug_reselected_ok:
2522 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2523 OPTION_DEBUG_DISCONNECT)) {
2524
2525
2526
2527
2528
2529 u32 *dsa;
2530 dsa = (u32 *) bus_to_virt (NCR53c7x0_read32(DSA_REG));
2531
2532 printk("scsi%d : reselected_ok (DSA = 0x%x (virt 0x%p)\n",
2533 host->host_no, NCR53c7x0_read32(DSA_REG), dsa);
2534 printk("scsi%d : resume address is 0x%x (virt 0x%p)\n",
2535 host->host_no, cmd->saved_data_pointer,
2536 bus_to_virt(cmd->saved_data_pointer));
2537 print_insn (host, hostdata->script + Ent_reselected_ok /
2538 sizeof(u32), "", 1);
2539 if ((hostdata->chip / 100) == 8)
2540 printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n",
2541 host->host_no, NCR53c7x0_read8(SXFER_REG),
2542 NCR53c7x0_read8(SCNTL3_REG_800));
2543 else
2544 printk ("scsi%d : sxfer=0x%x, cannot read SBCL\n",
2545 host->host_no, NCR53c7x0_read8(SXFER_REG));
2546 if (c) {
2547 print_insn (host, (u32 *)
2548 hostdata->sync[c->device->id].script, "", 1);
2549 print_insn (host, (u32 *)
2550 hostdata->sync[c->device->id].script + 2, "", 1);
2551 }
2552 }
2553 return SPECIFIC_INT_RESTART;
2554#endif
2555#ifdef A_int_debug_reselect_check
2556 case A_int_debug_reselect_check:
2557 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2558 u32 *dsa;
2559#if 0
2560 u32 *code;
2561#endif
2562
2563
2564
2565
2566
2567 dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG));
2568 printk("scsi%d : reselected_check_next (DSA = 0x%lx (virt 0x%p))\n",
2569 host->host_no, virt_to_bus(dsa), dsa);
2570 if (dsa) {
2571 printk("scsi%d : resume address is 0x%x (virt 0x%p)\n",
2572 host->host_no, cmd->saved_data_pointer,
2573 bus_to_virt (cmd->saved_data_pointer));
2574#if 0
2575 printk("scsi%d : template code :\n", host->host_no);
2576 for (code = dsa + (Ent_dsa_code_check_reselect - Ent_dsa_zero)
2577 / sizeof(u32); code < (dsa + Ent_dsa_zero / sizeof(u32));
2578 code += print_insn (host, code, "", 1));
2579#endif
2580 }
2581 print_insn (host, hostdata->script + Ent_reselected_ok /
2582 sizeof(u32), "", 1);
2583 }
2584 return SPECIFIC_INT_RESTART;
2585#endif
2586#ifdef A_int_debug_dsa_schedule
2587 case A_int_debug_dsa_schedule:
2588 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2589 u32 *dsa;
2590
2591
2592
2593
2594
2595 dsa = (u32 *) bus_to_virt (NCR53c7x0_read32(DSA_REG));
2596 printk("scsi%d : dsa_schedule (old DSA = 0x%lx (virt 0x%p))\n",
2597 host->host_no, virt_to_bus(dsa), dsa);
2598 if (dsa)
2599 printk("scsi%d : resume address is 0x%x (virt 0x%p)\n"
2600 " (temp was 0x%x (virt 0x%p))\n",
2601 host->host_no, cmd->saved_data_pointer,
2602 bus_to_virt (cmd->saved_data_pointer),
2603 NCR53c7x0_read32 (TEMP_REG),
2604 bus_to_virt (NCR53c7x0_read32(TEMP_REG)));
2605 }
2606 return SPECIFIC_INT_RESTART;
2607#endif
2608#ifdef A_int_debug_scheduled
2609 case A_int_debug_scheduled:
2610 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2611 printk("scsi%d : new I/O 0x%x (virt 0x%p) scheduled\n",
2612 host->host_no, NCR53c7x0_read32(DSA_REG),
2613 bus_to_virt(NCR53c7x0_read32(DSA_REG)));
2614 }
2615 return SPECIFIC_INT_RESTART;
2616#endif
2617#ifdef A_int_debug_idle
2618 case A_int_debug_idle:
2619 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2620 printk("scsi%d : idle\n", host->host_no);
2621 }
2622 return SPECIFIC_INT_RESTART;
2623#endif
2624#ifdef A_int_debug_cmd
2625 case A_int_debug_cmd:
2626 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2627 printk("scsi%d : command sent\n");
2628 }
2629 return SPECIFIC_INT_RESTART;
2630#endif
2631#ifdef A_int_debug_dsa_loaded
2632 case A_int_debug_dsa_loaded:
2633 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2634 printk("scsi%d : DSA loaded with 0x%x (virt 0x%p)\n", host->host_no,
2635 NCR53c7x0_read32(DSA_REG),
2636 bus_to_virt(NCR53c7x0_read32(DSA_REG)));
2637 }
2638 return SPECIFIC_INT_RESTART;
2639#endif
2640#ifdef A_int_debug_reselected
2641 case A_int_debug_reselected:
2642 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2643 OPTION_DEBUG_DISCONNECT)) {
2644 if ((hostdata->chip / 100) == 8)
2645 printk("scsi%d : reselected by target %d lun %d\n",
2646 host->host_no, (int) NCR53c7x0_read8(SDID_REG_800) & ~0x80,
2647 (int) hostdata->reselected_identify & 7);
2648 else
2649 printk("scsi%d : reselected by LCRC=0x%02x lun %d\n",
2650 host->host_no, (int) NCR53c7x0_read8(LCRC_REG_10),
2651 (int) hostdata->reselected_identify & 7);
2652 print_queues(host);
2653 }
2654 return SPECIFIC_INT_RESTART;
2655#endif
2656#ifdef A_int_debug_disconnect_msg
2657 case A_int_debug_disconnect_msg:
2658 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2659 if (c)
2660 printk("scsi%d : target %d lun %d disconnecting\n",
2661 host->host_no, c->device->id, c->device->lun);
2662 else
2663 printk("scsi%d : unknown target disconnecting\n",
2664 host->host_no);
2665 }
2666 return SPECIFIC_INT_RESTART;
2667#endif
2668#ifdef A_int_debug_disconnected
2669 case A_int_debug_disconnected:
2670 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2671 OPTION_DEBUG_DISCONNECT)) {
2672 printk ("scsi%d : disconnected, new queues are\n",
2673 host->host_no);
2674 print_queues(host);
2675#if 0
2676
2677 printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n",
2678 host->host_no, NCR53c7x0_read8(SXFER_REG),
2679 NCR53c7x0_read8(SCNTL3_REG_800));
2680#endif
2681 if (c) {
2682 print_insn (host, (u32 *)
2683 hostdata->sync[c->device->id].script, "", 1);
2684 print_insn (host, (u32 *)
2685 hostdata->sync[c->device->id].script + 2, "", 1);
2686 }
2687 }
2688 return SPECIFIC_INT_RESTART;
2689#endif
2690#ifdef A_int_debug_panic
2691 case A_int_debug_panic:
2692 printk("scsi%d : int_debug_panic received\n", host->host_no);
2693 print_lots (host);
2694 return SPECIFIC_INT_PANIC;
2695#endif
2696#ifdef A_int_debug_saved
2697 case A_int_debug_saved:
2698 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2699 OPTION_DEBUG_DISCONNECT)) {
2700 printk ("scsi%d : saved data pointer 0x%x (virt 0x%p)\n",
2701 host->host_no, cmd->saved_data_pointer,
2702 bus_to_virt (cmd->saved_data_pointer));
2703 print_progress (c);
2704 }
2705 return SPECIFIC_INT_RESTART;
2706#endif
2707#ifdef A_int_debug_restored
2708 case A_int_debug_restored:
2709 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2710 OPTION_DEBUG_DISCONNECT)) {
2711 if (cmd) {
2712 int size;
2713 printk ("scsi%d : restored data pointer 0x%x (virt 0x%p)\n",
2714 host->host_no, cmd->saved_data_pointer, bus_to_virt (
2715 cmd->saved_data_pointer));
2716 size = print_insn (host, (u32 *)
2717 bus_to_virt(cmd->saved_data_pointer), "", 1);
2718 size = print_insn (host, (u32 *)
2719 bus_to_virt(cmd->saved_data_pointer) + size, "", 1);
2720 print_progress (c);
2721 }
2722#if 0
2723 printk ("scsi%d : datapath residual %d\n",
2724 host->host_no, datapath_residual (host)) ;
2725#endif
2726 }
2727 return SPECIFIC_INT_RESTART;
2728#endif
2729#ifdef A_int_debug_sync
2730 case A_int_debug_sync:
2731 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2732 OPTION_DEBUG_DISCONNECT|OPTION_DEBUG_SDTR)) {
2733 unsigned char sxfer = NCR53c7x0_read8 (SXFER_REG), scntl3;
2734 if ((hostdata->chip / 100) == 8) {
2735 scntl3 = NCR53c7x0_read8 (SCNTL3_REG_800);
2736 if (c) {
2737 if (sxfer != hostdata->sync[c->device->id].sxfer_sanity ||
2738 scntl3 != hostdata->sync[c->device->id].scntl3_sanity) {
2739 printk ("scsi%d : sync sanity check failed sxfer=0x%x, scntl3=0x%x",
2740 host->host_no, sxfer, scntl3);
2741 NCR53c7x0_write8 (SXFER_REG, sxfer);
2742 NCR53c7x0_write8 (SCNTL3_REG_800, scntl3);
2743 }
2744 } else
2745 printk ("scsi%d : unknown command sxfer=0x%x, scntl3=0x%x\n",
2746 host->host_no, (int) sxfer, (int) scntl3);
2747 } else {
2748 if (c) {
2749 if (sxfer != hostdata->sync[c->device->id].sxfer_sanity) {
2750 printk ("scsi%d : sync sanity check failed sxfer=0x%x",
2751 host->host_no, sxfer);
2752 NCR53c7x0_write8 (SXFER_REG, sxfer);
2753 NCR53c7x0_write8 (SBCL_REG,
2754 hostdata->sync[c->device->id].sscf_710);
2755 }
2756 } else
2757 printk ("scsi%d : unknown command sxfer=0x%x\n",
2758 host->host_no, (int) sxfer);
2759 }
2760 }
2761 return SPECIFIC_INT_RESTART;
2762#endif
2763#ifdef A_int_debug_datain
2764 case A_int_debug_datain:
2765 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2766 OPTION_DEBUG_DISCONNECT|OPTION_DEBUG_SDTR)) {
2767 int size;
2768 if ((hostdata->chip / 100) == 8)
2769 printk ("scsi%d : In do_datain (%s) sxfer=0x%x, scntl3=0x%x\n"
2770 " datapath residual=%d\n",
2771 host->host_no, sbcl_to_phase (NCR53c7x0_read8 (SBCL_REG)),
2772 (int) NCR53c7x0_read8(SXFER_REG),
2773 (int) NCR53c7x0_read8(SCNTL3_REG_800),
2774 datapath_residual (host)) ;
2775 else
2776 printk ("scsi%d : In do_datain (%s) sxfer=0x%x\n"
2777 " datapath residual=%d\n",
2778 host->host_no, sbcl_to_phase (NCR53c7x0_read8 (SBCL_REG)),
2779 (int) NCR53c7x0_read8(SXFER_REG),
2780 datapath_residual (host)) ;
2781 print_insn (host, dsp, "", 1);
2782 size = print_insn (host, (u32 *) bus_to_virt(dsp[1]), "", 1);
2783 print_insn (host, (u32 *) bus_to_virt(dsp[1]) + size, "", 1);
2784 }
2785 return SPECIFIC_INT_RESTART;
2786#endif
2787#ifdef A_int_debug_check_dsa
2788 case A_int_debug_check_dsa:
2789 if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) {
2790 int sdid;
2791 int tmp;
2792 char *where;
2793 if (hostdata->chip / 100 == 8)
2794 sdid = NCR53c7x0_read8 (SDID_REG_800) & 15;
2795 else {
2796 tmp = NCR53c7x0_read8 (SDID_REG_700);
2797 if (!tmp)
2798 panic ("SDID_REG_700 = 0");
2799 tmp >>= 1;
2800 sdid = 0;
2801 while (tmp) {
2802 tmp >>= 1;
2803 sdid++;
2804 }
2805 }
2806 where = dsp - NCR53c7x0_insn_size(NCR53c7x0_read8
2807 (DCMD_REG)) == hostdata->script +
2808 Ent_select_check_dsa / sizeof(u32) ?
2809 "selection" : "reselection";
2810 if (c && sdid != c->device->id) {
2811 printk ("scsi%d : SDID target %d != DSA target %d at %s\n",
2812 host->host_no, sdid, c->device->id, where);
2813 print_lots(host);
2814 dump_events (host, 20);
2815 return SPECIFIC_INT_PANIC;
2816 }
2817 }
2818 return SPECIFIC_INT_RESTART;
2819#endif
2820 default:
2821 if ((dsps & 0xff000000) == 0x03000000) {
2822 printk ("scsi%d : misc debug interrupt 0x%x\n",
2823 host->host_no, dsps);
2824 return SPECIFIC_INT_RESTART;
2825 } else if ((dsps & 0xff000000) == 0x05000000) {
2826 if (hostdata->events) {
2827 struct NCR53c7x0_event *event;
2828 ++hostdata->event_index;
2829 if (hostdata->event_index >= hostdata->event_size)
2830 hostdata->event_index = 0;
2831 event = (struct NCR53c7x0_event *) hostdata->events +
2832 hostdata->event_index;
2833 event->event = (enum ncr_event) dsps;
2834 event->dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
2835 if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) {
2836 if (hostdata->chip / 100 == 8)
2837 event->target = NCR53c7x0_read8(SSID_REG_800);
2838 else {
2839 unsigned char tmp, sdid;
2840 tmp = NCR53c7x0_read8 (SDID_REG_700);
2841 if (!tmp)
2842 panic ("SDID_REG_700 = 0");
2843 tmp >>= 1;
2844 sdid = 0;
2845 while (tmp) {
2846 tmp >>= 1;
2847 sdid++;
2848 }
2849 event->target = sdid;
2850 }
2851 }
2852 else
2853 event->target = 255;
2854
2855 if (event->event == EVENT_RESELECT)
2856 event->lun = hostdata->reselected_identify & 0xf;
2857 else if (c)
2858 event->lun = c->device->lun;
2859 else
2860 event->lun = 255;
2861 do_gettimeofday(&(event->time));
2862 if (c) {
2863 event->pid = c->pid;
2864 memcpy ((void *) event->cmnd, (void *) c->cmnd,
2865 sizeof (event->cmnd));
2866 } else {
2867 event->pid = -1;
2868 }
2869 }
2870 return SPECIFIC_INT_RESTART;
2871 }
2872
2873 printk ("scsi%d : unknown user interrupt 0x%x\n",
2874 host->host_no, (unsigned) dsps);
2875 return SPECIFIC_INT_PANIC;
2876 }
2877}
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893#include "53c7xx_u.h"
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910static void
2911NCR53c7x0_soft_reset (struct Scsi_Host *host) {
2912 NCR53c7x0_local_declare();
2913 unsigned long flags;
2914 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2915 host->hostdata[0];
2916 NCR53c7x0_local_setup(host);
2917
2918 local_irq_save(flags);
2919
2920
2921
2922#ifdef CONFIG_MVME16x
2923 if (MACH_IS_MVME16x)
2924 {
2925 volatile unsigned long v;
2926
2927 v = *(volatile unsigned long *)0xfff4006c;
2928 v &= ~0x8000;
2929 *(volatile unsigned long *)0xfff4006c = v;
2930 v = *(volatile unsigned long *)0xfff4202c;
2931 v &= ~0x10;
2932 *(volatile unsigned long *)0xfff4202c = v;
2933 }
2934#endif
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949 NCR53c7x0_write8(ISTAT_REG_700, ISTAT_10_SRST);
2950 NCR53c7x0_write8(ISTAT_REG_700, 0);
2951
2952
2953
2954
2955
2956
2957
2958 hostdata->saved_dcntl = DCNTL_10_EA|DCNTL_10_COM;
2959 if (hostdata->scsi_clock > 50000000)
2960 hostdata->saved_dcntl |= DCNTL_700_CF_3;
2961 else
2962 if (hostdata->scsi_clock > 37500000)
2963 hostdata->saved_dcntl |= DCNTL_700_CF_2;
2964#if 0
2965 else
2966
2967#endif
2968
2969 if (hostdata->options & OPTION_DEBUG_TRACE)
2970 NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl | DCNTL_SSM);
2971 else
2972 NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl);
2973
2974
2975
2976
2977
2978
2979
2980 NCR53c7x0_write8(CTEST7_REG, CTEST7_10_TT1|CTEST7_STD);
2981
2982 NCR53c7x0_write8(hostdata->dmode, DMODE_10_BL_8 | DMODE_10_FC2);
2983 NCR53c7x0_write8(SCID_REG, 1 << host->this_id);
2984 NCR53c7x0_write8(SBCL_REG, 0);
2985 NCR53c7x0_write8(SCNTL1_REG, SCNTL1_ESR_700);
2986 NCR53c7x0_write8(SCNTL0_REG, ((hostdata->options & OPTION_PARITY) ?
2987 SCNTL0_EPC : 0) | SCNTL0_EPG_700 | SCNTL0_ARB1 | SCNTL0_ARB2);
2988
2989
2990
2991
2992
2993
2994 NCR53c7x0_write8(DIEN_REG, DIEN_700_BF |
2995 DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_700_OPC);
2996
2997 NCR53c7x0_write8(SIEN_REG_700, ((hostdata->options & OPTION_PARITY) ?
2998 SIEN_PAR : 0) | SIEN_700_STO | SIEN_RST | SIEN_UDC |
2999 SIEN_SGE | SIEN_MA);
3000
3001#ifdef CONFIG_MVME16x
3002 if (MACH_IS_MVME16x)
3003 {
3004 volatile unsigned long v;
3005
3006
3007 v = *(volatile unsigned long *)0xfff40080;
3008 v = (v & ~(0xf << 28)) | (4 << 28);
3009 *(volatile unsigned long *)0xfff40080 = v;
3010 v = *(volatile unsigned long *)0xfff4006c;
3011 v |= 0x8000;
3012 *(volatile unsigned long *)0xfff4006c = v;
3013 v = *(volatile unsigned long *)0xfff4202c;
3014 v = (v & ~0xff) | 0x10 | 4;
3015 *(volatile unsigned long *)0xfff4202c = v;
3016 }
3017#endif
3018
3019 local_irq_restore(flags);
3020}
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040static void
3041my_free_page (void *addr, int dummy)
3042{
3043
3044
3045
3046 kernel_set_cachemode((void *)addr, 4096, IOMAP_FULL_CACHING);
3047 free_page ((u32)addr);
3048}
3049
3050static struct NCR53c7x0_cmd *
3051allocate_cmd (Scsi_Cmnd *cmd) {
3052 struct Scsi_Host *host = cmd->device->host;
3053 struct NCR53c7x0_hostdata *hostdata =
3054 (struct NCR53c7x0_hostdata *) host->hostdata[0];
3055 u32 real;
3056 int size;
3057 struct NCR53c7x0_cmd *tmp;
3058 unsigned long flags;
3059
3060 if (hostdata->options & OPTION_DEBUG_ALLOCATION)
3061 printk ("scsi%d : num_cmds = %d, can_queue = %d\n"
3062 " target = %d, lun = %d, %s\n",
3063 host->host_no, hostdata->num_cmds, host->can_queue,
3064 cmd->device->id, cmd->device->lun, (hostdata->cmd_allocated[cmd->device->id] &
3065 (1 << cmd->device->lun)) ? "already allocated" : "not allocated");
3066
3067
3068
3069
3070
3071
3072
3073 if (!(hostdata->cmd_allocated[cmd->device->id] & (1 << cmd->device->lun)) &&
3074 cmd->device && cmd->device->has_cmdblocks) {
3075 if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue)
3076 hostdata->extra_allocate += host->cmd_per_lun;
3077 hostdata->cmd_allocated[cmd->device->id] |= (1 << cmd->device->lun);
3078 }
3079
3080 for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate,
3081 ++hostdata->num_cmds) {
3082
3083
3084 size = hostdata->max_cmd_size + sizeof (void *);
3085#ifdef FORCE_DSA_ALIGNMENT
3086
3087
3088
3089
3090 size += 256;
3091#endif
3092
3093
3094 if (size > 4096) {
3095 printk (KERN_ERR "53c7xx: allocate_cmd size > 4K\n");
3096 return NULL;
3097 }
3098 real = get_zeroed_page(GFP_ATOMIC);
3099 if (real == 0)
3100 return NULL;
3101 memset((void *)real, 0, 4096);
3102 cache_push(virt_to_phys((void *)real), 4096);
3103 cache_clear(virt_to_phys((void *)real), 4096);
3104 kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER);
3105 tmp = ROUNDUP(real, void *);
3106#ifdef FORCE_DSA_ALIGNMENT
3107 {
3108 if (((u32)tmp & 0xff) > CmdPageStart)
3109 tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255);
3110 tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart);
3111#if 0
3112 printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n",
3113 size, real, (u32)tmp);
3114#endif
3115 }
3116#endif
3117 tmp->real = (void *)real;
3118 tmp->size = size;
3119 tmp->free = ((void (*)(void *, int)) my_free_page);
3120 local_irq_save(flags);
3121 tmp->next = hostdata->free;
3122 hostdata->free = tmp;
3123 local_irq_restore(flags);
3124 }
3125 local_irq_save(flags);
3126 tmp = (struct NCR53c7x0_cmd *) hostdata->free;
3127 if (tmp) {
3128 hostdata->free = tmp->next;
3129 }
3130 local_irq_restore(flags);
3131 if (!tmp)
3132 printk ("scsi%d : can't allocate command for target %d lun %d\n",
3133 host->host_no, cmd->device->id, cmd->device->lun);
3134 return tmp;
3135}
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150static struct NCR53c7x0_cmd *
3151create_cmd (Scsi_Cmnd *cmd) {
3152 NCR53c7x0_local_declare();
3153 struct Scsi_Host *host = cmd->device->host;
3154 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3155 host->hostdata[0];
3156 struct NCR53c7x0_cmd *tmp;
3157 int datain,
3158 dataout;
3159 int data_transfer_instructions,
3160 i;
3161 u32 *cmd_datain,
3162 *cmd_dataout;
3163#ifdef notyet
3164 unsigned char *msgptr;
3165 int msglen;
3166#endif
3167 unsigned long flags;
3168 u32 exp_select_indirect;
3169 NCR53c7x0_local_setup(cmd->device->host);
3170
3171 if (!(tmp = allocate_cmd (cmd)))
3172 return NULL;
3173
3174
3175
3176
3177
3178
3179
3180 memcpy(tmp->cmnd, cmd->cmnd, 12);
3181 tmp->result = cmd->result;
3182
3183
3184
3185
3186
3187
3188 switch (cmd->cmnd[0]) {
3189
3190 case INQUIRY:
3191 case MODE_SENSE:
3192 case READ_6:
3193 case READ_10:
3194 case READ_CAPACITY:
3195 case REQUEST_SENSE:
3196 case READ_BLOCK_LIMITS:
3197 case READ_TOC:
3198 datain = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
3199 dataout = 0;
3200 break;
3201
3202 case MODE_SELECT:
3203 case WRITE_6:
3204 case WRITE_10:
3205#if 0
3206 printk("scsi%d : command is ", host->host_no);
3207 print_command(cmd->cmnd);
3208#endif
3209#if 0
3210 printk ("scsi%d : %d scatter/gather segments\n", host->host_no,
3211 cmd->use_sg);
3212#endif
3213 datain = 0;
3214 dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
3215#if 0
3216 hostdata->options |= OPTION_DEBUG_INTR;
3217#endif
3218 break;
3219
3220
3221
3222
3223 case TEST_UNIT_READY:
3224 case ALLOW_MEDIUM_REMOVAL:
3225 case START_STOP:
3226 datain = dataout = 0;
3227 break;
3228
3229
3230
3231
3232
3233 default:
3234 printk("scsi%d : datain+dataout for command ", host->host_no);
3235 print_command(cmd->cmnd);
3236 datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
3237 }
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261 data_transfer_instructions = datain + dataout;
3262
3263
3264
3265
3266
3267
3268
3269 if (data_transfer_instructions < 2)
3270 data_transfer_instructions = 2;
3271
3272
3273
3274
3275
3276
3277
3278 tmp->saved_data_pointer = virt_to_bus (hostdata->script) +
3279 hostdata->E_data_transfer;
3280
3281
3282
3283
3284
3285 tmp->cmd = cmd;
3286 tmp->next = NULL;
3287 tmp->flags = 0;
3288 tmp->dsa_next_addr = virt_to_bus(tmp->dsa) + hostdata->dsa_next -
3289 hostdata->dsa_start;
3290 tmp->dsa_addr = virt_to_bus(tmp->dsa) - hostdata->dsa_start;
3291
3292
3293
3294
3295
3296 tmp->data_transfer_start = tmp->dsa + (hostdata->dsa_end -
3297 hostdata->dsa_start) / sizeof(u32);
3298 tmp->data_transfer_end = tmp->data_transfer_start +
3299 2 * data_transfer_instructions;
3300
3301 cmd_datain = datain ? tmp->data_transfer_start : NULL;
3302 cmd_dataout = dataout ? (datain ? cmd_datain + 2 * datain : tmp->
3303 data_transfer_start) : NULL;
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313 if (hostdata->dsa_fixup)
3314 hostdata->dsa_fixup(tmp);
3315
3316 patch_dsa_32(tmp->dsa, dsa_next, 0, 0);
3317
3318
3319
3320
3321 patch_dsa_32(tmp->dsa, dsa_cmnd, 0, virt_to_bus(cmd));
3322
3323 if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS) {
3324
3325 exp_select_indirect = ((1 << cmd->device->id) << 16) |
3326 (hostdata->sync[cmd->device->id].sxfer_sanity << 8);
3327
3328 if (hostdata->sync[cmd->device->id].select_indirect !=
3329 exp_select_indirect) {
3330 printk ("scsi%d : sanity check failed select_indirect=0x%x\n",
3331 host->host_no, hostdata->sync[cmd->device->id].select_indirect);
3332 FATAL(host);
3333
3334 }
3335 }
3336
3337 patch_dsa_32(tmp->dsa, dsa_select, 0,
3338 hostdata->sync[cmd->device->id].select_indirect);
3339
3340
3341
3342
3343
3344
3345 if (hostdata->initiate_wdtr & (1 << cmd->device->id)) {
3346 memcpy ((void *) (tmp->select + 1), (void *) wdtr_message,
3347 sizeof(wdtr_message));
3348 patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(wdtr_message));
3349 local_irq_save(flags);
3350 hostdata->initiate_wdtr &= ~(1 << cmd->device->id);
3351 local_irq_restore(flags);
3352 } else if (hostdata->initiate_sdtr & (1 << cmd->device->id)) {
3353 memcpy ((void *) (tmp->select + 1), (void *) sdtr_message,
3354 sizeof(sdtr_message));
3355 patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(sdtr_message));
3356 tmp->flags |= CMD_FLAG_SDTR;
3357 local_irq_save(flags);
3358 hostdata->initiate_sdtr &= ~(1 << cmd->device->id);
3359 local_irq_restore(flags);
3360
3361 }
3362#if 1
3363 else if (!(hostdata->talked_to & (1 << cmd->device->id)) &&
3364 !(hostdata->options & OPTION_NO_ASYNC)) {
3365
3366 memcpy ((void *) (tmp->select + 1), (void *) async_message,
3367 sizeof(async_message));
3368 patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(async_message));
3369 tmp->flags |= CMD_FLAG_SDTR;
3370 }
3371#endif
3372 else
3373 patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
3374
3375 hostdata->talked_to |= (1 << cmd->device->id);
3376 tmp->select[0] = (hostdata->options & OPTION_DISCONNECT) ?
3377 IDENTIFY (1, cmd->device->lun) : IDENTIFY (0, cmd->device->lun);
3378 patch_dsa_32(tmp->dsa, dsa_msgout, 1, virt_to_bus(tmp->select));
3379 patch_dsa_32(tmp->dsa, dsa_cmdout, 0, cmd->cmd_len);
3380 patch_dsa_32(tmp->dsa, dsa_cmdout, 1, virt_to_bus(tmp->cmnd));
3381 patch_dsa_32(tmp->dsa, dsa_dataout, 0, cmd_dataout ?
3382 virt_to_bus (cmd_dataout)
3383 : virt_to_bus (hostdata->script) + hostdata->E_other_transfer);
3384 patch_dsa_32(tmp->dsa, dsa_datain, 0, cmd_datain ?
3385 virt_to_bus (cmd_datain)
3386 : virt_to_bus (hostdata->script) + hostdata->E_other_transfer);
3387
3388
3389
3390
3391 patch_dsa_32(tmp->dsa, dsa_msgin, 0, 1);
3392
3393
3394
3395
3396
3397#ifdef BIG_ENDIAN
3398 patch_dsa_32(tmp->dsa, dsa_msgin, 1, virt_to_bus(&tmp->result) + 2);
3399 patch_dsa_32(tmp->dsa, dsa_status, 0, 1);
3400 patch_dsa_32(tmp->dsa, dsa_status, 1, virt_to_bus(&tmp->result) + 3);
3401#else
3402 patch_dsa_32(tmp->dsa, dsa_msgin, 1, virt_to_bus(&tmp->result) + 1);
3403 patch_dsa_32(tmp->dsa, dsa_status, 0, 1);
3404 patch_dsa_32(tmp->dsa, dsa_status, 1, virt_to_bus(&tmp->result));
3405#endif
3406 patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, 1);
3407 patch_dsa_32(tmp->dsa, dsa_msgout_other, 1,
3408 virt_to_bus(&(hostdata->NCR53c7xx_msg_nop)));
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425#if 0
3426 if (datain) {
3427 cmd_datain[0] = 0x98080000;
3428 cmd_datain[1] = 0x03ffd00d;
3429 cmd_datain += 2;
3430 }
3431#endif
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448 tmp->bounce.len = 0;
3449
3450 for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4,
3451 cmd_dataout += 4, ++i) {
3452 u32 vbuf = cmd->use_sg
3453 ? (u32)page_address(((struct scatterlist *)cmd->buffer)[i].page)+
3454 ((struct scatterlist *)cmd->buffer)[i].offset
3455 : (u32)(cmd->request_buffer);
3456 u32 bbuf = virt_to_bus((void *)vbuf);
3457 u32 count = cmd->use_sg ?
3458 ((struct scatterlist *)cmd->buffer)[i].length :
3459 cmd->request_bufflen;
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470 if (((bbuf & 15) || (count & 15)) && (datain || dataout))
3471 {
3472
3473 if (cmd->use_sg)
3474 printk ("53c7xx: Non-aligned buffer with use_sg\n");
3475 else if (datain && dataout)
3476 printk ("53c7xx: Non-aligned buffer with datain && dataout\n");
3477 else if (count > 256)
3478 printk ("53c7xx: Non-aligned transfer > 256 bytes\n");
3479 else
3480 {
3481 if (datain)
3482 {
3483 tmp->bounce.len = count;
3484 tmp->bounce.addr = vbuf;
3485 bbuf = virt_to_bus(tmp->bounce.buf);
3486 tmp->bounce.buf[0] = 0xff;
3487 tmp->bounce.buf[1] = 0xfe;
3488 tmp->bounce.buf[2] = 0xfd;
3489 tmp->bounce.buf[3] = 0xfc;
3490 }
3491 if (dataout)
3492 {
3493 memcpy ((void *)tmp->bounce.buf, (void *)vbuf, count);
3494 bbuf = virt_to_bus(tmp->bounce.buf);
3495 }
3496 }
3497 }
3498
3499 if (datain) {
3500 cache_clear(virt_to_phys((void *)vbuf), count);
3501
3502 cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
3503 DCMD_TCI_IO) << 24) |
3504 DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
3505 cmd_datain[1] = virt_to_bus (hostdata->script) +
3506 hostdata->E_other_in;
3507
3508 cmd_datain[2] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | DCMD_BMI_IO)
3509 << 24) | count;
3510 cmd_datain[3] = bbuf;
3511#if 0
3512 print_insn (host, cmd_datain, "dynamic ", 1);
3513 print_insn (host, cmd_datain + 2, "dynamic ", 1);
3514#endif
3515 }
3516 if (dataout) {
3517 cache_push(virt_to_phys((void *)vbuf), count);
3518
3519 cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL) << 24) |
3520 DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
3521 cmd_dataout[1] = virt_to_bus(hostdata->script) +
3522 hostdata->E_other_out;
3523
3524 cmd_dataout[2] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I) << 24)
3525 | count;
3526 cmd_dataout[3] = bbuf;
3527#if 0
3528 print_insn (host, cmd_dataout, "dynamic ", 1);
3529 print_insn (host, cmd_dataout + 2, "dynamic ", 1);
3530#endif
3531 }
3532 }
3533
3534
3535
3536
3537
3538
3539
3540 if (datain) {
3541 cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
3542 DBC_TCI_TRUE;
3543 cmd_datain[1] = virt_to_bus(hostdata->script) +
3544 hostdata->E_other_transfer;
3545#if 0
3546 print_insn (host, cmd_datain, "dynamic jump ", 1);
3547#endif
3548 cmd_datain += 2;
3549 }
3550#if 0
3551 if (datain) {
3552 cmd_datain[0] = 0x98080000;
3553 cmd_datain[1] = 0x03ffdeed;
3554 cmd_datain += 2;
3555 }
3556#endif
3557 if (dataout) {
3558 cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
3559 DBC_TCI_TRUE;
3560 cmd_dataout[1] = virt_to_bus(hostdata->script) +
3561 hostdata->E_other_transfer;
3562#if 0
3563 print_insn (host, cmd_dataout, "dynamic jump ", 1);
3564#endif
3565 cmd_dataout += 2;
3566 }
3567
3568 return tmp;
3569}
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592int
3593NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
3594 struct Scsi_Host *host = cmd->device->host;
3595 struct NCR53c7x0_hostdata *hostdata =
3596 (struct NCR53c7x0_hostdata *) host->hostdata[0];
3597 unsigned long flags;
3598 Scsi_Cmnd *tmp;
3599
3600 cmd->scsi_done = done;
3601 cmd->host_scribble = NULL;
3602 cmd->SCp.ptr = NULL;
3603 cmd->SCp.buffer = NULL;
3604
3605#ifdef VALID_IDS
3606
3607 if (!hostdata->valid_ids[cmd->device->id]) {
3608 printk("scsi%d : ignoring target %d lun %d\n", host->host_no,
3609 cmd->device->id, cmd->device->lun);
3610 cmd->result = (DID_BAD_TARGET << 16);
3611 done(cmd);
3612 return 0;
3613 }
3614#endif
3615
3616 local_irq_save(flags);
3617 if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY))
3618 || ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
3619 !(hostdata->debug_lun_limit[cmd->device->id] & (1 << cmd->device->lun)))
3620#ifdef LINUX_1_2
3621 || cmd->device->id > 7
3622#else
3623 || cmd->device->id > host->max_id
3624#endif
3625 || cmd->device->id == host->this_id
3626 || hostdata->state == STATE_DISABLED) {
3627 printk("scsi%d : disabled or bad target %d lun %d\n", host->host_no,
3628 cmd->device->id, cmd->device->lun);
3629 cmd->result = (DID_BAD_TARGET << 16);
3630 done(cmd);
3631 local_irq_restore(flags);
3632 return 0;
3633 }
3634
3635 if ((hostdata->options & OPTION_DEBUG_NCOMMANDS_LIMIT) &&
3636 (hostdata->debug_count_limit == 0)) {
3637 printk("scsi%d : maximum commands exceeded\n", host->host_no);
3638 cmd->result = (DID_BAD_TARGET << 16);
3639 done(cmd);
3640 local_irq_restore(flags);
3641 return 0;
3642 }
3643
3644 if (hostdata->options & OPTION_DEBUG_READ_ONLY) {
3645 switch (cmd->cmnd[0]) {
3646 case WRITE_6:
3647 case WRITE_10:
3648 printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
3649 host->host_no);
3650 cmd->result = (DID_BAD_TARGET << 16);
3651 done(cmd);
3652 local_irq_restore(flags);
3653 return 0;
3654 }
3655 }
3656
3657 if ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
3658 hostdata->debug_count_limit != -1)
3659 --hostdata->debug_count_limit;
3660
3661 cmd->result = 0xffff;
3662
3663 cmd->host_scribble = (unsigned char *) tmp = create_cmd (cmd);
3664
3665
3666
3667
3668
3669
3670
3671 if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
3672 cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
3673 hostdata->issue_queue = cmd;
3674 } else {
3675 for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->SCp.ptr;
3676 tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
3677 tmp->SCp.ptr = (unsigned char *) cmd;
3678 }
3679 local_irq_restore(flags);
3680 run_process_issue_queue();
3681 return 0;
3682}
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703static __inline__ void
3704to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
3705 struct NCR53c7x0_cmd *cmd) {
3706 NCR53c7x0_local_declare();
3707 Scsi_Cmnd *tmp = cmd->cmd;
3708 unsigned long flags;
3709
3710 volatile u32 *ncrcurrent;
3711
3712 int i;
3713 NCR53c7x0_local_setup(host);
3714#if 0
3715 printk("scsi%d : new dsa is 0x%lx (virt 0x%p)\n", host->host_no,
3716 virt_to_bus(hostdata->dsa), hostdata->dsa);
3717#endif
3718
3719 local_irq_save(flags);
3720
3721
3722
3723
3724
3725
3726 if (hostdata->state == STATE_DISABLED) {
3727 printk("scsi%d : driver disabled\n", host->host_no);
3728 tmp->result = (DID_BAD_TARGET << 16);
3729 cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
3730 hostdata->free = cmd;
3731 tmp->scsi_done(tmp);
3732 local_irq_restore(flags);
3733 return;
3734 }
3735
3736 for (i = host->can_queue, ncrcurrent = hostdata->schedule;
3737 i > 0 && ncrcurrent[0] != hostdata->NOP_insn;
3738 --i, ncrcurrent += 2 );
3739
3740 if (i > 0) {
3741 ++hostdata->busy[tmp->device->id][tmp->device->lun];
3742 cmd->next = hostdata->running_list;
3743 hostdata->running_list = cmd;
3744
3745
3746 cmd->dsa [(hostdata->dsa_jump_dest - hostdata->dsa_start) /
3747 sizeof(u32)] = (u32) virt_to_bus ((void *)ncrcurrent);
3748
3749 ncrcurrent[1] =
3750 virt_to_bus ((void *) cmd->dsa) + hostdata->E_dsa_code_begin -
3751 hostdata->E_dsa_code_template;
3752
3753 ncrcurrent[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) |
3754 DBC_TCI_TRUE;
3755 } else {
3756 printk ("scsi%d: no free slot\n", host->host_no);
3757 disable(host);
3758 tmp->result = (DID_ERROR << 16);
3759 cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
3760 hostdata->free = cmd;
3761 tmp->scsi_done(tmp);
3762 local_irq_restore(flags);
3763 return;
3764 }
3765
3766
3767
3768
3769
3770
3771
3772 if (hostdata->idle) {
3773 hostdata->idle = 0;
3774 hostdata->state = STATE_RUNNING;
3775 NCR53c7x0_write32 (DSP_REG, virt_to_bus ((void *)hostdata->schedule));
3776 if (hostdata->options & OPTION_DEBUG_TRACE)
3777 NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl |
3778 DCNTL_SSM | DCNTL_STD);
3779 } else {
3780 NCR53c7x0_write8(hostdata->istat, ISTAT_10_SIGP);
3781 }
3782
3783 local_irq_restore(flags);
3784}
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796static __inline__ int
3797busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
3798 Scsi_Cmnd *cmd) {
3799
3800
3801
3802 return hostdata->busy[cmd->device->id][cmd->device->lun];
3803}
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822static void
3823process_issue_queue (unsigned long flags) {
3824 Scsi_Cmnd *tmp, *prev;
3825 struct Scsi_Host *host;
3826 struct NCR53c7x0_hostdata *hostdata;
3827 int done;
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840 do {
3841 local_irq_disable();
3842 done = 1;
3843 for (host = first_host; host && host->hostt == the_template;
3844 host = host->next) {
3845 hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
3846 local_irq_disable();
3847 if (hostdata->issue_queue) {
3848 if (hostdata->state == STATE_DISABLED) {
3849 tmp = (Scsi_Cmnd *) hostdata->issue_queue;
3850 hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
3851 tmp->result = (DID_BAD_TARGET << 16);
3852 if (tmp->host_scribble) {
3853 ((struct NCR53c7x0_cmd *)tmp->host_scribble)->next =
3854 hostdata->free;
3855 hostdata->free =
3856 (struct NCR53c7x0_cmd *)tmp->host_scribble;
3857 tmp->host_scribble = NULL;
3858 }
3859 tmp->scsi_done (tmp);
3860 done = 0;
3861 } else
3862 for (tmp = (Scsi_Cmnd *) hostdata->issue_queue,
3863 prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *)
3864 tmp->SCp.ptr)
3865 if (!tmp->host_scribble ||
3866 !busyp (host, hostdata, tmp)) {
3867 if (prev)
3868 prev->SCp.ptr = tmp->SCp.ptr;
3869 else
3870 hostdata->issue_queue = (Scsi_Cmnd *)
3871 tmp->SCp.ptr;
3872 tmp->SCp.ptr = NULL;
3873 if (tmp->host_scribble) {
3874 if (hostdata->options & OPTION_DEBUG_QUEUES)
3875 printk ("scsi%d : moving command for target %d lun %d to start list\n",
3876 host->host_no, tmp->device->id, tmp->device->lun);
3877
3878
3879 to_schedule_list (host, hostdata,
3880 (struct NCR53c7x0_cmd *)
3881 tmp->host_scribble);
3882 } else {
3883 if (((tmp->result & 0xff) == 0xff) ||
3884 ((tmp->result & 0xff00) == 0xff00)) {
3885 printk ("scsi%d : danger Will Robinson!\n",
3886 host->host_no);
3887 tmp->result = DID_ERROR << 16;
3888 disable (host);
3889 }
3890 tmp->scsi_done(tmp);
3891 }
3892 done = 0;
3893 }
3894 }
3895 if (!done)
3896 local_irq_restore(flags);
3897 }
3898 } while (!done);
3899 process_issue_queue_running = 0;
3900}
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913static void
3914intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
3915 NCR53c7x0_local_declare();
3916 struct NCR53c7x0_hostdata *hostdata =
3917 (struct NCR53c7x0_hostdata *) host->hostdata[0];
3918 unsigned char sstat0_sist0, sist1,
3919 fatal;
3920
3921
3922 NCR53c7x0_local_setup(host);
3923
3924 fatal = 0;
3925
3926 sstat0_sist0 = NCR53c7x0_read8(SSTAT0_REG);
3927 sist1 = 0;
3928
3929 if (hostdata->options & OPTION_DEBUG_INTR)
3930 printk ("scsi%d : SIST0 0x%0x, SIST1 0x%0x\n", host->host_no,
3931 sstat0_sist0, sist1);
3932
3933
3934 if (sstat0_sist0 & SSTAT0_700_STO) {
3935 fatal = 1;
3936 if (hostdata->options & OPTION_DEBUG_INTR) {
3937 printk ("scsi%d : Selection Timeout\n", host->host_no);
3938 if (cmd) {
3939 printk("scsi%d : target %d, lun %d, command ",
3940 host->host_no, cmd->cmd->device->id, cmd->cmd->device->lun);
3941 print_command (cmd->cmd->cmnd);
3942 printk("scsi%d : dsp = 0x%x (virt 0x%p)\n", host->host_no,
3943 NCR53c7x0_read32(DSP_REG),
3944 bus_to_virt(NCR53c7x0_read32(DSP_REG)));
3945 } else {
3946 printk("scsi%d : no command\n", host->host_no);
3947 }
3948 }
3949
3950
3951
3952
3953
3954
3955 if (1) {
3956 hostdata->idle = 1;
3957 hostdata->expecting_sto = 0;
3958
3959 if (hostdata->test_running) {
3960 hostdata->test_running = 0;
3961 hostdata->test_completed = 3;
3962 } else if (cmd) {
3963 abnormal_finished(cmd, DID_BAD_TARGET << 16);
3964 }
3965#if 0
3966 hostdata->intrs = 0;
3967#endif
3968 }
3969 }
3970
3971
3972
3973
3974 if (sstat0_sist0 & SSTAT0_UDC) {
3975 fatal = 1;
3976 if (cmd) {
3977 printk("scsi%d : target %d lun %d unexpected disconnect\n",
3978 host->host_no, cmd->cmd->device->id, cmd->cmd->device->lun);
3979 print_lots (host);
3980 abnormal_finished(cmd, DID_ERROR << 16);
3981 } else
3982 printk("scsi%d : unexpected disconnect (no command)\n",
3983 host->host_no);
3984
3985 hostdata->dsp = (u32 *) hostdata->schedule;
3986 hostdata->dsp_changed = 1;
3987 }
3988
3989
3990 if (sstat0_sist0 & SSTAT0_PAR) {
3991 fatal = 1;
3992 if (cmd && cmd->cmd) {
3993 printk("scsi%d : target %d lun %d parity error.\n",
3994 host->host_no, cmd->cmd->device->id, cmd->cmd->device->lun);
3995 abnormal_finished (cmd, DID_PARITY << 16);
3996 } else
3997 printk("scsi%d : parity error\n", host->host_no);
3998
3999
4000
4001 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
4002 sizeof(u32);
4003 hostdata->dsp_changed = 1;
4004
4005 }
4006
4007 if (sstat0_sist0 & SSTAT0_SGE) {
4008 fatal = 1;
4009 printk("scsi%d : gross error, saved2_dsa = 0x%x\n", host->host_no,
4010 (unsigned int)hostdata->saved2_dsa);
4011 print_lots (host);
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
4030 sizeof(u32);
4031 hostdata->dsp_changed = 1;
4032
4033 }
4034
4035 if (sstat0_sist0 & SSTAT0_MA) {
4036 fatal = 1;
4037 if (hostdata->options & OPTION_DEBUG_INTR)
4038 printk ("scsi%d : SSTAT0_MA\n", host->host_no);
4039 intr_phase_mismatch (host, cmd);
4040 }
4041
4042#if 0
4043 if (sstat0_sist0 & SIST0_800_RSL)
4044 printk ("scsi%d : Oh no Mr. Bill!\n", host->host_no);
4045#endif
4046
4047
4048
4049
4050
4051
4052 if (fatal) {
4053 if (!hostdata->dstat_valid) {
4054 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
4055 hostdata->dstat_valid = 1;
4056 }
4057
4058 if (!(hostdata->dstat & DSTAT_DFE)) {
4059 printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
4060
4061
4062
4063
4064
4065 NCR53c7x0_write8 (CTEST8_REG, CTEST8_10_CLF);
4066 while (NCR53c7x0_read8 (CTEST8_REG) & CTEST8_10_CLF)
4067 ;
4068 hostdata->dstat |= DSTAT_DFE;
4069 }
4070 }
4071}
4072
4073#ifdef CYCLIC_TRACE
4074
4075
4076
4077
4078
4079
4080
4081u32 insn_log[4096];
4082u32 insn_log_index = 0;
4083
4084void log1 (u32 i)
4085{
4086 insn_log[insn_log_index++] = i;
4087 if (insn_log_index == 4096)
4088 insn_log_index = 0;
4089}
4090
4091void log_insn (u32 *ip)
4092{
4093 log1 ((u32)ip);
4094 log1 (*ip);
4095 log1 (*(ip+1));
4096 if (((*ip >> 24) & DCMD_TYPE_MASK) == DCMD_TYPE_MMI)
4097 log1 (*(ip+2));
4098}
4099
4100void dump_log(void)
4101{
4102 int cnt = 0;
4103 int i = insn_log_index;
4104 int size;
4105 struct Scsi_Host *host = first_host;
4106
4107 while (cnt < 4096) {
4108 printk ("%08x (+%6x): ", insn_log[i], (insn_log[i] - (u32)&(((struct NCR53c7x0_hostdata *)host->hostdata[0])->script))/4);
4109 if (++i == 4096)
4110 i = 0;
4111 cnt++;
4112 if (((insn_log[i] >> 24) & DCMD_TYPE_MASK) == DCMD_TYPE_MMI)
4113 size = 3;
4114 else
4115 size = 2;
4116 while (size--) {
4117 printk ("%08x ", insn_log[i]);
4118 if (++i == 4096)
4119 i = 0;
4120 cnt++;
4121 }
4122 printk ("\n");
4123 }
4124}
4125#endif
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140static void
4141NCR53c7x0_intfly (struct Scsi_Host *host)
4142{
4143 NCR53c7x0_local_declare();
4144 struct NCR53c7x0_hostdata *hostdata;
4145 struct NCR53c7x0_cmd *cmd,
4146 **cmd_prev_ptr;
4147 unsigned long flags;
4148 char search_found = 0;
4149
4150 hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
4151 NCR53c7x0_local_setup(host);
4152
4153 if (hostdata->options & OPTION_DEBUG_INTR)
4154 printk ("scsi%d : INTFLY\n", host->host_no);
4155
4156
4157
4158
4159
4160
4161
4162
4163 local_irq_save(flags);
4164restart:
4165 for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)&(hostdata->running_list),
4166 cmd = (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
4167 cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next),
4168 cmd = (struct NCR53c7x0_cmd *) cmd->next)
4169 {
4170 Scsi_Cmnd *tmp;
4171
4172 if (!cmd) {
4173 printk("scsi%d : very weird.\n", host->host_no);
4174 break;
4175 }
4176
4177 if (!(tmp = cmd->cmd)) {
4178 printk("scsi%d : weird. NCR53c7x0_cmd has no Scsi_Cmnd\n",
4179 host->host_no);
4180 continue;
4181 }
4182
4183
4184
4185
4186 tmp->result = cmd->result;
4187
4188 if (((tmp->result & 0xff) == 0xff) ||
4189 ((tmp->result & 0xff00) == 0xff00))
4190 continue;
4191
4192 search_found = 1;
4193
4194 if (cmd->bounce.len)
4195 memcpy ((void *)cmd->bounce.addr,
4196 (void *)cmd->bounce.buf, cmd->bounce.len);
4197
4198
4199 if (cmd_prev_ptr)
4200 *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next;
4201
4202 --hostdata->busy[tmp->device->id][tmp->device->lun];
4203 cmd->next = hostdata->free;
4204 hostdata->free = cmd;
4205
4206 tmp->host_scribble = NULL;
4207
4208 if (hostdata->options & OPTION_DEBUG_INTR) {
4209 printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 0x%x ",
4210 host->host_no, tmp->pid, tmp->device->id, tmp->device->lun, tmp->result);
4211 print_command (tmp->cmnd);
4212 }
4213
4214 tmp->scsi_done(tmp);
4215 goto restart;
4216 }
4217 local_irq_restore(flags);
4218
4219 if (!search_found) {
4220 printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
4221 host->host_no);
4222 } else {
4223 run_process_issue_queue();
4224 }
4225 return;
4226}
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242static irqreturn_t
4243NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs)
4244{
4245 NCR53c7x0_local_declare();
4246 struct Scsi_Host *host;
4247 unsigned char istat;
4248 struct NCR53c7x0_hostdata *hostdata;
4249 struct NCR53c7x0_cmd *cmd;
4250 u32 *dsa;
4251 int handled = 0;
4252
4253#ifdef NCR_DEBUG
4254 char buf[80];
4255 size_t buflen;
4256#endif
4257
4258 host = (struct Scsi_Host *)dev_id;
4259 hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
4260 NCR53c7x0_local_setup(host);
4261
4262
4263
4264
4265
4266
4267 while ((istat = NCR53c7x0_read8(hostdata->istat)) & (ISTAT_SIP|ISTAT_DIP)) {
4268 handled = 1;
4269 hostdata->dsp_changed = 0;
4270 hostdata->dstat_valid = 0;
4271 hostdata->state = STATE_HALTED;
4272
4273 if (NCR53c7x0_read8 (SSTAT2_REG) & SSTAT2_FF_MASK)
4274 printk ("scsi%d : SCSI FIFO not empty\n", host->host_no);
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286 if (hostdata->options & OPTION_700) {
4287 cmd = (struct NCR53c7x0_cmd *) hostdata->ncrcurrent;
4288 } else {
4289 dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
4290 for (cmd = (struct NCR53c7x0_cmd *) hostdata->running_list;
4291 cmd && (dsa + (hostdata->dsa_start / sizeof(u32))) != cmd->dsa;
4292 cmd = (struct NCR53c7x0_cmd *)(cmd->next))
4293 ;
4294 }
4295 if (hostdata->options & OPTION_DEBUG_INTR) {
4296 if (cmd) {
4297 printk("scsi%d : interrupt for pid %lu, id %d, lun %d ",
4298 host->host_no, cmd->cmd->pid, (int) cmd->cmd->device->id,
4299 (int) cmd->cmd->device->lun);
4300 print_command (cmd->cmd->cmnd);
4301 } else {
4302 printk("scsi%d : no active command\n", host->host_no);
4303 }
4304 }
4305
4306 if (istat & ISTAT_SIP) {
4307 if (hostdata->options & OPTION_DEBUG_INTR)
4308 printk ("scsi%d : ISTAT_SIP\n", host->host_no);
4309 intr_scsi (host, cmd);
4310 }
4311
4312 if (istat & ISTAT_DIP) {
4313 if (hostdata->options & OPTION_DEBUG_INTR)
4314 printk ("scsi%d : ISTAT_DIP\n", host->host_no);
4315 intr_dma (host, cmd);
4316 }
4317
4318 if (!hostdata->dstat_valid) {
4319 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
4320 hostdata->dstat_valid = 1;
4321 }
4322
4323 if (!(hostdata->dstat & DSTAT_DFE)) {
4324 printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
4325
4326 NCR53c7x0_write8 (CTEST8_REG, CTEST8_10_CLF);
4327 while (NCR53c7x0_read8 (CTEST8_REG) & CTEST8_10_CLF)
4328 ;
4329 hostdata->dstat |= DSTAT_DFE;
4330 }
4331
4332 if (!hostdata->idle && hostdata->state == STATE_HALTED) {
4333 if (!hostdata->dsp_changed)
4334 hostdata->dsp = (u32 *)bus_to_virt(NCR53c7x0_read32(DSP_REG));
4335#if 0
4336 printk("scsi%d : new dsp is 0x%lx (virt 0x%p)\n",
4337 host->host_no, virt_to_bus(hostdata->dsp), hostdata->dsp);
4338#endif
4339
4340 hostdata->state = STATE_RUNNING;
4341 NCR53c7x0_write32 (DSP_REG, virt_to_bus(hostdata->dsp));
4342 if (hostdata->options & OPTION_DEBUG_TRACE) {
4343#ifdef CYCLIC_TRACE
4344 log_insn (hostdata->dsp);
4345#else
4346 print_insn (host, hostdata->dsp, "t ", 1);
4347#endif
4348 NCR53c7x0_write8 (DCNTL_REG,
4349 hostdata->saved_dcntl | DCNTL_SSM | DCNTL_STD);
4350 }
4351 }
4352 }
4353 return IRQ_HANDLED;
4354}
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369static int
4370abort_connected (struct Scsi_Host *host) {
4371#ifdef NEW_ABORT
4372 NCR53c7x0_local_declare();
4373#endif
4374 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
4375 host->hostdata[0];
4376
4377
4378 static int counter = 5;
4379#ifdef NEW_ABORT
4380 int sstat, phase, offset;
4381 u32 *script;
4382 NCR53c7x0_local_setup(host);
4383#endif
4384
4385 if (--counter <= 0) {
4386 disable(host);
4387 return 0;
4388 }
4389
4390 printk ("scsi%d : DANGER : abort_connected() called \n",
4391 host->host_no);
4392
4393#ifdef NEW_ABORT
4394
4395
4396
4397
4398
4399
4400
4401
4402 sstat = (NCR53c8x0_read8 (SSTAT2_REG);
4403 offset = OFFSET (sstat & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
4404 phase = sstat & SSTAT2_PHASE_MASK;
4405
4406
4407
4408
4409
4410
4411
4412
4413 script = hostdata->abort_script = kmalloc (
4414 8 * (
4415 1 +
4416 (!offset ? 1 : offset) +
4417 1 ),
4418 GFP_ATOMIC);
4419
4420
4421#else
4422 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
4423 sizeof(u32);
4424#endif
4425 hostdata->dsp_changed = 1;
4426
4427
4428
4429
4430 return 0;
4431}
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441static int
4442datapath_residual (struct Scsi_Host *host) {
4443 NCR53c7x0_local_declare();
4444 int count, synchronous, sstat;
4445 unsigned int ddir;
4446
4447 NCR53c7x0_local_setup(host);
4448
4449 count = ((NCR53c7x0_read8 (DFIFO_REG) & DFIFO_10_BO_MASK) -
4450 (NCR53c7x0_read32 (DBC_REG) & DFIFO_10_BO_MASK)) & DFIFO_10_BO_MASK;
4451 synchronous = NCR53c7x0_read8 (SXFER_REG) & SXFER_MO_MASK;
4452
4453 ddir = NCR53c7x0_read8 (CTEST0_REG_700) & CTEST0_700_DDIR;
4454
4455 if (ddir) {
4456
4457 if (synchronous)
4458 count += (NCR53c7x0_read8 (SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
4459 else
4460 if (NCR53c7x0_read8 (SSTAT1_REG) & SSTAT1_ILF)
4461 ++count;
4462 } else {
4463
4464 sstat = NCR53c7x0_read8 (SSTAT1_REG);
4465 if (sstat & SSTAT1_OLF)
4466 ++count;
4467 if (synchronous && (sstat & SSTAT1_ORF))
4468 ++count;
4469 }
4470 return count;
4471}
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482static const char *
4483sbcl_to_phase (int sbcl) {
4484 switch (sbcl & SBCL_PHASE_MASK) {
4485 case SBCL_PHASE_DATAIN:
4486 return "DATAIN";
4487 case SBCL_PHASE_DATAOUT:
4488 return "DATAOUT";
4489 case SBCL_PHASE_MSGIN:
4490 return "MSGIN";
4491 case SBCL_PHASE_MSGOUT:
4492 return "MSGOUT";
4493 case SBCL_PHASE_CMDOUT:
4494 return "CMDOUT";
4495 case SBCL_PHASE_STATIN:
4496 return "STATUSIN";
4497 default:
4498 return "unknown";
4499 }
4500}
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511static const char *
4512sstat2_to_phase (int sstat) {
4513 switch (sstat & SSTAT2_PHASE_MASK) {
4514 case SSTAT2_PHASE_DATAIN:
4515 return "DATAIN";
4516 case SSTAT2_PHASE_DATAOUT:
4517 return "DATAOUT";
4518 case SSTAT2_PHASE_MSGIN:
4519 return "MSGIN";
4520 case SSTAT2_PHASE_MSGOUT:
4521 return "MSGOUT";
4522 case SSTAT2_PHASE_CMDOUT:
4523 return "CMDOUT";
4524 case SSTAT2_PHASE_STATIN:
4525 return "STATUSIN";
4526 default:
4527 return "unknown";
4528 }
4529}
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546static void
4547intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
4548 NCR53c7x0_local_declare();
4549 u32 dbc_dcmd, *dsp, *dsp_next;
4550 unsigned char dcmd, sbcl;
4551 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
4552 host->hostdata[0];
4553 int residual;
4554 enum {ACTION_ABORT, ACTION_ABORT_PRINT, ACTION_CONTINUE} action =
4555 ACTION_ABORT_PRINT;
4556 const char *where = NULL;
4557
4558 NCR53c7x0_local_setup(host);
4559
4560
4561
4562
4563
4564 dsp_next = bus_to_virt(NCR53c7x0_read32(DSP_REG));
4565
4566
4567
4568
4569
4570 dbc_dcmd = NCR53c7x0_read32(DBC_REG);
4571 dcmd = (dbc_dcmd & 0xff000000) >> 24;
4572
4573
4574
4575
4576
4577 dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
4578
4579
4580
4581
4582
4583
4584
4585 sbcl = NCR53c7x0_read8(SBCL_REG) & SBCL_PHASE_MASK;
4586
4587 if (!cmd) {
4588 action = ACTION_ABORT_PRINT;
4589 where = "no current command";
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608 } else if (((dsp >= cmd->data_transfer_start &&
4609 dsp < cmd->data_transfer_end)) || dsp == (cmd->residual + 2)) {
4610 if ((dcmd & (DCMD_TYPE_MASK|DCMD_BMI_OP_MASK|DCMD_BMI_INDIRECT|
4611 DCMD_BMI_MSG|DCMD_BMI_CD)) == (DCMD_TYPE_BMI|
4612 DCMD_BMI_OP_MOVE_I)) {
4613 residual = datapath_residual (host);
4614 if (hostdata->options & OPTION_DEBUG_DISCONNECT)
4615 printk ("scsi%d : handling residual transfer (+ %d bytes from DMA FIFO)\n",
4616 host->host_no, residual);
4617
4618
4619
4620
4621
4622
4623
4624 if (dsp != cmd->residual + 2) {
4625 cmd->residual[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
4626 ((dcmd & DCMD_BMI_IO) ? DCMD_TCI_IO : 0)) << 24) |
4627 DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
4628 cmd->residual[1] = virt_to_bus(hostdata->script)
4629 + ((dcmd & DCMD_BMI_IO)
4630 ? hostdata->E_other_in : hostdata->E_other_out);
4631 }
4632
4633
4634
4635
4636
4637
4638 cmd->residual[2] = dbc_dcmd + residual;
4639 cmd->residual[3] = NCR53c7x0_read32(DNAD_REG) - residual;
4640
4641
4642
4643
4644
4645 if (dsp != cmd->residual + 2) {
4646 cmd->residual[4] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP)
4647 << 24) | DBC_TCI_TRUE;
4648 cmd->residual[5] = virt_to_bus(dsp_next);
4649 }
4650
4651
4652
4653
4654
4655 hostdata->dsp = cmd->residual;
4656 hostdata->dsp_changed = 1;
4657 action = ACTION_CONTINUE;
4658 } else {
4659 where = "non-BMI dynamic DSA code";
4660 action = ACTION_ABORT_PRINT;
4661 }
4662 } else if (dsp == (hostdata->script + hostdata->E_select_msgout / 4 + 2)) {
4663
4664
4665
4666 NCR53c7x0_write8 (SOCL_REG, 0);
4667 switch (sbcl) {
4668
4669
4670
4671
4672
4673
4674 case SBCL_PHASE_CMDOUT:
4675 hostdata->dsp = dsp + 2 ;
4676 hostdata->dsp_changed = 1;
4677 printk ("scsi%d : target %d ignored SDTR and went into COMMAND OUT\n",
4678 host->host_no, cmd->cmd->device->id);
4679 cmd->flags &= ~CMD_FLAG_SDTR;
4680 action = ACTION_CONTINUE;
4681 break;
4682 case SBCL_PHASE_MSGIN:
4683 hostdata->dsp = hostdata->script + hostdata->E_msg_in /
4684 sizeof(u32);
4685 hostdata->dsp_changed = 1;
4686 action = ACTION_CONTINUE;
4687 break;
4688 default:
4689 where="select message out";
4690 action = ACTION_ABORT_PRINT;
4691 }
4692
4693
4694
4695
4696
4697 } else if (dsp == hostdata->script + hostdata->E_cmdout_cmdout / sizeof
4698 (u32)) {
4699 hostdata->dsp = hostdata->script + hostdata->E_data_transfer /
4700 sizeof (u32);
4701 hostdata->dsp_changed = 1;
4702 action = ACTION_CONTINUE;
4703
4704#ifdef notyet
4705 } else if (dsp == hostdata->script + hostdata->E_reply_message) {
4706 switch (sbcl) {
4707
4708#endif
4709 } else {
4710 where = "unknown location";
4711 action = ACTION_ABORT_PRINT;
4712 }
4713
4714
4715 if (!hostdata->dstat_valid) {
4716 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
4717 hostdata->dstat_valid = 1;
4718 }
4719 if (!(hostdata->dstat & DSTAT_DFE)) {
4720
4721 NCR53c7x0_write8 (CTEST8_REG, CTEST8_10_CLF);
4722 while (NCR53c7x0_read8 (CTEST8_REG) & CTEST8_10_CLF);
4723 hostdata->dstat |= DSTAT_DFE;
4724 }
4725
4726 switch (action) {
4727 case ACTION_ABORT_PRINT:
4728 printk("scsi%d : %s : unexpected phase %s.\n",
4729 host->host_no, where ? where : "unknown location",
4730 sbcl_to_phase(sbcl));
4731 print_lots (host);
4732
4733 case ACTION_ABORT:
4734 abort_connected (host);
4735 break;
4736 case ACTION_CONTINUE:
4737 break;
4738 }
4739
4740#if 0
4741 if (hostdata->dsp_changed) {
4742 printk("scsi%d: new dsp 0x%p\n", host->host_no, hostdata->dsp);
4743 print_insn (host, hostdata->dsp, "", 1);
4744 }
4745#endif
4746}
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758static void
4759intr_bf (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
4760 NCR53c7x0_local_declare();
4761 u32 *dsp,
4762 *next_dsp,
4763 *dsa,
4764 dbc_dcmd;
4765 char *reason = NULL;
4766
4767
4768 enum {MAYBE, ALWAYS, NEVER} retry = MAYBE;
4769 int report = 0;
4770 NCR53c7x0_local_setup(host);
4771
4772 dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
4773 next_dsp = bus_to_virt (NCR53c7x0_read32(DSP_REG));
4774 dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
4775
4776 dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG));
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792 report = 1;
4793 reason = "Unknown";
4794
4795#ifndef notyet
4796 report = 1;
4797#endif
4798 if (report && reason)
4799 {
4800 printk(KERN_ALERT "scsi%d : BUS FAULT reason = %s\n",
4801 host->host_no, reason ? reason : "unknown");
4802 print_lots (host);
4803 }
4804
4805#ifndef notyet
4806 retry = NEVER;
4807#endif
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818 if (retry == NEVER) {
4819 printk(KERN_ALERT " mail richard@sleepie.demon.co.uk\n");
4820 FATAL (host);
4821 }
4822}
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835static void
4836intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
4837 NCR53c7x0_local_declare();
4838 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
4839 host->hostdata[0];
4840 unsigned char dstat;
4841 u32 *dsp,
4842 *next_dsp,
4843 *dsa,
4844 dbc_dcmd;
4845 int tmp;
4846 unsigned long flags;
4847 NCR53c7x0_local_setup(host);
4848
4849 if (!hostdata->dstat_valid) {
4850 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
4851 hostdata->dstat_valid = 1;
4852 }
4853
4854 dstat = hostdata->dstat;
4855
4856 if (hostdata->options & OPTION_DEBUG_INTR)
4857 printk("scsi%d : DSTAT=0x%x\n", host->host_no, (int) dstat);
4858
4859 dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
4860 next_dsp = bus_to_virt(NCR53c7x0_read32(DSP_REG));
4861 dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
4862
4863 dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876 if (dstat & DSTAT_ABRT) {
4877#if 0
4878
4879 if ((hostdata->options & OPTION_700) && (hostdata->state ==
4880 STATE_ABORTING)) {
4881 } else
4882#endif
4883 {
4884 printk(KERN_ALERT "scsi%d : unexpected abort interrupt at\n"
4885 " ", host->host_no);
4886 print_insn (host, dsp, KERN_ALERT "s ", 1);
4887 FATAL (host);
4888 }
4889 }
4890
4891
4892
4893
4894
4895
4896 if (dstat & DSTAT_SSI) {
4897 if (hostdata->options & OPTION_DEBUG_TRACE) {
4898
4899 } else if (hostdata->options & OPTION_DEBUG_SINGLE) {
4900 print_insn (host, dsp, "s ", 0);
4901 local_irq_save(flags);
4902
4903
4904 NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) &
4905 ~DCNTL_SSM) | DCNTL_STD);
4906 local_irq_restore(flags);
4907 } else {
4908 printk(KERN_ALERT "scsi%d : unexpected single step interrupt at\n"
4909 " ", host->host_no);
4910 print_insn (host, dsp, KERN_ALERT "", 1);
4911 printk(KERN_ALERT " mail drew@PoohSticks.ORG\n");
4912 FATAL (host);
4913 }
4914 }
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926 if (dstat & DSTAT_OPC) {
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939 if (((dsp >= (hostdata->script + hostdata->E_select / sizeof(u32))) &&
4940 (dsp <= (hostdata->script + hostdata->E_select_msgout /
4941 sizeof(u32) + 8))) || (hostdata->test_running == 2)) {
4942 if (hostdata->options & OPTION_DEBUG_INTR)
4943 printk ("scsi%d : ignoring DSTAT_IID for SSTAT_STO\n",
4944 host->host_no);
4945 if (hostdata->expecting_iid) {
4946 hostdata->expecting_iid = 0;
4947 hostdata->idle = 1;
4948 if (hostdata->test_running == 2) {
4949 hostdata->test_running = 0;
4950 hostdata->test_completed = 3;
4951 } else if (cmd)
4952 abnormal_finished (cmd, DID_BAD_TARGET << 16);
4953 } else {
4954 hostdata->expecting_sto = 1;
4955 }
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971 } else if (dbc_dcmd == 0x48000000 && (NCR53c7x0_read8 (SBCL_REG) &
4972 SBCL_REQ)) {
4973 if (!(hostdata->options & OPTION_NO_PRINT_RACE))
4974 {
4975 printk("scsi%d: REQ before WAIT DISCONNECT IID\n",
4976 host->host_no);
4977 hostdata->options |= OPTION_NO_PRINT_RACE;
4978 }
4979 } else {
4980 printk(KERN_ALERT "scsi%d : invalid instruction\n", host->host_no);
4981 print_lots (host);
4982 printk(KERN_ALERT " mail Richard@sleepie.demon.co.uk with ALL\n"
4983 " boot messages and diagnostic output\n");
4984 FATAL (host);
4985 }
4986 }
4987
4988
4989
4990
4991
4992 if (dstat & DSTAT_800_BF) {
4993 intr_bf (host, cmd);
4994 }
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005 if (dstat & DSTAT_SIR) {
5006 if (hostdata->options & OPTION_DEBUG_INTR)
5007 printk ("scsi%d : DSTAT_SIR\n", host->host_no);
5008 switch ((tmp = hostdata->dstat_sir_intr (host, cmd))) {
5009 case SPECIFIC_INT_NOTHING:
5010 case SPECIFIC_INT_RESTART:
5011 break;
5012 case SPECIFIC_INT_ABORT:
5013 abort_connected(host);
5014 break;
5015 case SPECIFIC_INT_PANIC:
5016 printk(KERN_ALERT "scsi%d : failure at ", host->host_no);
5017 print_insn (host, dsp, KERN_ALERT "", 1);
5018 printk(KERN_ALERT " dstat_sir_intr() returned SPECIFIC_INT_PANIC\n");
5019 FATAL (host);
5020 break;
5021 case SPECIFIC_INT_BREAK:
5022 intr_break (host, cmd);
5023 break;
5024 default:
5025 printk(KERN_ALERT "scsi%d : failure at ", host->host_no);
5026 print_insn (host, dsp, KERN_ALERT "", 1);
5027 printk(KERN_ALERT" dstat_sir_intr() returned unknown value %d\n",
5028 tmp);
5029 FATAL (host);
5030 }
5031 }
5032}
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057static int
5058print_insn (struct Scsi_Host *host, const u32 *insn,
5059 const char *prefix, int kernel) {
5060 char buf[160],
5061
5062
5063
5064 *tmp;
5065 unsigned char dcmd;
5066 int size;
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078 if (virt_to_phys((void *)insn) < PAGE_SIZE ||
5079 virt_to_phys((void *)(insn + 8)) > virt_to_phys(high_memory) ||
5080 ((((dcmd = (insn[0] >> 24) & 0xff) & DCMD_TYPE_MMI) == DCMD_TYPE_MMI) &&
5081 virt_to_phys((void *)(insn + 12)) > virt_to_phys(high_memory))) {
5082 size = 0;
5083 sprintf (buf, "%s%p: address out of range\n",
5084 prefix, insn);
5085 } else {
5086
5087
5088
5089
5090#if !defined(CONFIG_MVME16x) && !defined(CONFIG_BVME6000)
5091 sprintf(buf, "%s0x%lx (virt 0x%p) : 0x%08x 0x%08x (virt 0x%p)",
5092 (prefix ? prefix : ""), virt_to_bus((void *) insn), insn,
5093 insn[0], insn[1], bus_to_virt (insn[1]));
5094#else
5095
5096 sprintf(buf, "%s0x%x (+%x) : 0x%08x 0x%08x",
5097 (prefix ? prefix : ""), (u32)insn, ((u32)insn -
5098 (u32)&(((struct NCR53c7x0_hostdata *)host->hostdata[0])->script))/4,
5099 insn[0], insn[1]);
5100#endif
5101 tmp = buf + strlen(buf);
5102 if ((dcmd & DCMD_TYPE_MASK) == DCMD_TYPE_MMI) {
5103#if !defined(CONFIG_MVME16x) && !defined(CONFIG_BVME6000)
5104 sprintf (tmp, " 0x%08x (virt 0x%p)\n", insn[2],
5105 bus_to_virt(insn[2]));
5106#else
5107
5108 sprintf (tmp, " 0x%08x\n", insn[2]);
5109#endif
5110 size = 3;
5111 } else {
5112 sprintf (tmp, "\n");
5113 size = 2;
5114 }
5115 }
5116
5117 if (kernel)
5118 printk ("%s", buf);
5119#ifdef NCR_DEBUG
5120 else {
5121 size_t len = strlen(buf);
5122 debugger_kernel_write(host, buf, len);
5123 }
5124#endif
5125 return size;
5126}
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140int
5141NCR53c7xx_abort (Scsi_Cmnd *cmd) {
5142 NCR53c7x0_local_declare();
5143 struct Scsi_Host *host = cmd->device->host;
5144 struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *)
5145 host->hostdata[0] : NULL;
5146 unsigned long flags;
5147 struct NCR53c7x0_cmd *curr, **prev;
5148 Scsi_Cmnd *me, **last;
5149#if 0
5150 static long cache_pid = -1;
5151#endif
5152
5153
5154 if (!host) {
5155 printk ("Bogus SCSI command pid %ld; no host structure\n",
5156 cmd->pid);
5157 return SCSI_ABORT_ERROR;
5158 } else if (!hostdata) {
5159 printk ("Bogus SCSI host %d; no hostdata\n", host->host_no);
5160 return SCSI_ABORT_ERROR;
5161 }
5162 NCR53c7x0_local_setup(host);
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177 if (NCR53c7x0_read8(hostdata->istat) & (ISTAT_DIP|ISTAT_SIP)) {
5178 printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no,
5179 cmd->pid);
5180 NCR53c7x0_intr (host->irq, NULL, NULL);
5181 return SCSI_ABORT_BUSY;
5182 }
5183
5184 local_irq_save(flags);
5185#if 0
5186 if (cache_pid == cmd->pid)
5187 panic ("scsi%d : bloody fetus %d\n", host->host_no, cmd->pid);
5188 else
5189 cache_pid = cmd->pid;
5190#endif
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203 for (me = (Scsi_Cmnd *) hostdata->issue_queue,
5204 last = (Scsi_Cmnd **) &(hostdata->issue_queue);
5205 me && me != cmd; last = (Scsi_Cmnd **)&(me->SCp.ptr),
5206 me = (Scsi_Cmnd *)me->SCp.ptr);
5207
5208 if (me) {
5209 *last = (Scsi_Cmnd *) me->SCp.ptr;
5210 if (me->host_scribble) {
5211 ((struct NCR53c7x0_cmd *)me->host_scribble)->next = hostdata->free;
5212 hostdata->free = (struct NCR53c7x0_cmd *) me->host_scribble;
5213 me->host_scribble = NULL;
5214 }
5215 cmd->result = DID_ABORT << 16;
5216 cmd->scsi_done(cmd);
5217 printk ("scsi%d : found command %ld in Linux issue queue\n",
5218 host->host_no, me->pid);
5219 local_irq_restore(flags);
5220 run_process_issue_queue();
5221 return SCSI_ABORT_SUCCESS;
5222 }
5223
5224
5225
5226
5227
5228
5229 for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list,
5230 prev = (struct NCR53c7x0_cmd **) &(hostdata->running_list);
5231 curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **)
5232 &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
5233
5234 if (curr) {
5235 if ((curr->result & 0xff) != 0xff && (curr->result & 0xff00) != 0xff00) {
5236 cmd->result = curr->result;
5237 if (prev)
5238 *prev = (struct NCR53c7x0_cmd *) curr->next;
5239 curr->next = (struct NCR53c7x0_cmd *) hostdata->free;
5240 cmd->host_scribble = NULL;
5241 hostdata->free = curr;
5242 cmd->scsi_done(cmd);
5243 printk ("scsi%d : found finished command %ld in running list\n",
5244 host->host_no, cmd->pid);
5245 local_irq_restore(flags);
5246 return SCSI_ABORT_NOT_RUNNING;
5247 } else {
5248 printk ("scsi%d : DANGER : command running, can not abort.\n",
5249 cmd->device->host->host_no);
5250 local_irq_restore(flags);
5251 return SCSI_ABORT_BUSY;
5252 }
5253 }
5254
5255
5256
5257
5258
5259
5260 curr = (struct NCR53c7x0_cmd *) cmd->host_scribble;
5261 if (curr) {
5262 curr->next = hostdata->free;
5263 hostdata->free = curr;
5264 cmd->host_scribble = NULL;
5265 }
5266
5267 if (curr == NULL || ((curr->result & 0xff00) == 0xff00) ||
5268 ((curr->result & 0xff) == 0xff)) {
5269 printk ("scsi%d : did this command ever run?\n", host->host_no);
5270 cmd->result = DID_ABORT << 16;
5271 } else {
5272 printk ("scsi%d : probably lost INTFLY, normal completion\n",
5273 host->host_no);
5274 cmd->result = curr->result;
5275
5276
5277
5278
5279
5280 --hostdata->busy[cmd->device->id][cmd->device->lun];
5281 }
5282 local_irq_restore(flags);
5283 cmd->scsi_done(cmd);
5284
5285
5286
5287
5288
5289 return SCSI_ABORT_NOT_RUNNING;
5290}
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303int
5304NCR53c7xx_reset (Scsi_Cmnd *cmd, unsigned int reset_flags) {
5305 NCR53c7x0_local_declare();
5306 unsigned long flags;
5307 int found = 0;
5308 struct NCR53c7x0_cmd * c;
5309 Scsi_Cmnd *tmp;
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324 Scsi_Cmnd *nuke_list = NULL;
5325 struct Scsi_Host *host = cmd->device->host;
5326 struct NCR53c7x0_hostdata *hostdata =
5327 (struct NCR53c7x0_hostdata *) host->hostdata[0];
5328
5329 NCR53c7x0_local_setup(host);
5330 local_irq_save(flags);
5331 ncr_halt (host);
5332 print_lots (host);
5333 dump_events (host, 30);
5334 ncr_scsi_reset (host);
5335 for (tmp = nuke_list = return_outstanding_commands (host, 1 ,
5336 0 ); tmp; tmp = (Scsi_Cmnd *) tmp->SCp.buffer)
5337 if (tmp == cmd) {
5338 found = 1;
5339 break;
5340 }
5341
5342
5343
5344
5345
5346 if (!found) {
5347 c = (struct NCR53c7x0_cmd *) cmd->host_scribble;
5348 if (c) {
5349 cmd->host_scribble = NULL;
5350 c->next = hostdata->free;
5351 hostdata->free = c;
5352 } else
5353 printk ("scsi%d: lost command %ld\n", host->host_no, cmd->pid);
5354 cmd->SCp.buffer = (struct scatterlist *) nuke_list;
5355 nuke_list = cmd;
5356 }
5357
5358 NCR53c7x0_driver_init (host);
5359 hostdata->soft_reset (host);
5360 if (hostdata->resets == 0)
5361 disable(host);
5362 else if (hostdata->resets != -1)
5363 --hostdata->resets;
5364 local_irq_restore(flags);
5365 for (; nuke_list; nuke_list = tmp) {
5366 tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
5367 nuke_list->result = DID_RESET << 16;
5368 nuke_list->scsi_done (nuke_list);
5369 }
5370 local_irq_restore(flags);
5371 return SCSI_RESET_SUCCESS;
5372}
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392static int
5393insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
5394 struct NCR53c7x0_hostdata *hostdata =
5395 (struct NCR53c7x0_hostdata *) cmd->device->host->hostdata[0];
5396 struct NCR53c7x0_cmd *ncmd =
5397 (struct NCR53c7x0_cmd *) cmd->host_scribble;
5398 int offset = 0, buffers;
5399 struct scatterlist *segment;
5400 char *ptr;
5401 int found = 0;
5402
5403
5404
5405
5406
5407
5408
5409 if (!check_address ((unsigned long) ncmd, sizeof (struct NCR53c7x0_cmd)) &&
5410 ((insn >= ncmd->data_transfer_start &&
5411 insn < ncmd->data_transfer_end) ||
5412 (insn >= ncmd->residual &&
5413 insn < (ncmd->residual +
5414 sizeof(ncmd->residual))))) {
5415 ptr = bus_to_virt(insn[3]);
5416
5417 if ((buffers = cmd->use_sg)) {
5418 for (offset = 0,
5419 segment = (struct scatterlist *) cmd->buffer;
5420 buffers && !((found = ((ptr >= (char *)page_address(segment->page)+segment->offset) &&
5421 (ptr < ((char *)page_address(segment->page)+segment->offset+segment->length)))));
5422 --buffers, offset += segment->length, ++segment)
5423#if 0
5424 printk("scsi%d: comparing 0x%p to 0x%p\n",
5425 cmd->device->host->host_no, saved, page_address(segment->page+segment->offset);
5426#else
5427 ;
5428#endif
5429 offset += ptr - ((char *)page_address(segment->page)+segment->offset);
5430 } else {
5431 found = 1;
5432 offset = ptr - (char *) (cmd->request_buffer);
5433 }
5434 } else if ((insn >= hostdata->script +
5435 hostdata->E_data_transfer / sizeof(u32)) &&
5436 (insn <= hostdata->script +
5437 hostdata->E_end_data_transfer / sizeof(u32))) {
5438 found = 1;
5439 offset = 0;
5440 }
5441 return found ? offset : -1;
5442}
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455static void
5456print_progress (Scsi_Cmnd *cmd) {
5457 NCR53c7x0_local_declare();
5458 struct NCR53c7x0_cmd *ncmd =
5459 (struct NCR53c7x0_cmd *) cmd->host_scribble;
5460 int offset, i;
5461 char *where;
5462 u32 *ptr;
5463 NCR53c7x0_local_setup (cmd->device->host);
5464
5465 if (check_address ((unsigned long) ncmd,sizeof (struct NCR53c7x0_cmd)) == 0)
5466 {
5467 printk("\nNCR53c7x0_cmd fields:\n");
5468 printk(" bounce.len=0x%x, addr=0x%0x, buf[]=0x%02x %02x %02x %02x\n",
5469 ncmd->bounce.len, ncmd->bounce.addr, ncmd->bounce.buf[0],
5470 ncmd->bounce.buf[1], ncmd->bounce.buf[2], ncmd->bounce.buf[3]);
5471 printk(" result=%04x, cdb[0]=0x%02x\n", ncmd->result, ncmd->cmnd[0]);
5472 }
5473
5474 for (i = 0; i < 2; ++i) {
5475 if (check_address ((unsigned long) ncmd,
5476 sizeof (struct NCR53c7x0_cmd)) == -1)
5477 continue;
5478 if (!i) {
5479 where = "saved";
5480 ptr = bus_to_virt(ncmd->saved_data_pointer);
5481 } else {
5482 where = "active";
5483 ptr = bus_to_virt (NCR53c7x0_read32 (DSP_REG) -
5484 NCR53c7x0_insn_size (NCR53c7x0_read8 (DCMD_REG)) *
5485 sizeof(u32));
5486 }
5487 offset = insn_to_offset (cmd, ptr);
5488
5489 if (offset != -1)
5490 printk ("scsi%d : %s data pointer at offset %d\n",
5491 cmd->device->host->host_no, where, offset);
5492 else {
5493 int size;
5494 printk ("scsi%d : can't determine %s data pointer offset\n",
5495 cmd->device->host->host_no, where);
5496 if (ncmd) {
5497 size = print_insn (cmd->device->host,
5498 bus_to_virt(ncmd->saved_data_pointer), "", 1);
5499 print_insn (cmd->device->host,
5500 bus_to_virt(ncmd->saved_data_pointer) + size * sizeof(u32),
5501 "", 1);
5502 }
5503 }
5504 }
5505}
5506
5507
5508static void
5509print_dsa (struct Scsi_Host *host, u32 *dsa, const char *prefix) {
5510 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
5511 host->hostdata[0];
5512 int i, len;
5513 char *ptr;
5514 Scsi_Cmnd *cmd;
5515
5516 if (check_address ((unsigned long) dsa, hostdata->dsa_end -
5517 hostdata->dsa_start) == -1) {
5518 printk("scsi%d : bad dsa virt 0x%p\n", host->host_no, dsa);
5519 return;
5520 }
5521 printk("%sscsi%d : dsa at phys 0x%lx (virt 0x%p)\n"
5522 " + %d : dsa_msgout length = %u, data = 0x%x (virt 0x%p)\n" ,
5523 prefix ? prefix : "",
5524 host->host_no, virt_to_bus (dsa), dsa, hostdata->dsa_msgout,
5525 dsa[hostdata->dsa_msgout / sizeof(u32)],
5526 dsa[hostdata->dsa_msgout / sizeof(u32) + 1],
5527 bus_to_virt (dsa[hostdata->dsa_msgout / sizeof(u32) + 1]));
5528
5529
5530
5531
5532
5533
5534
5535 if (dsa[hostdata->dsa_msgout / sizeof(u32)] <
5536 sizeof (hostdata->free->select))
5537 for (i = dsa[hostdata->dsa_msgout / sizeof(u32)],
5538 ptr = bus_to_virt (dsa[hostdata->dsa_msgout / sizeof(u32) + 1]);
5539 i > 0 && !check_address ((unsigned long) ptr, 1);
5540 ptr += len, i -= len) {
5541 printk(" ");
5542 len = print_msg (ptr);
5543 printk("\n");
5544 if (!len)
5545 break;
5546 }
5547
5548 printk(" + %d : select_indirect = 0x%x\n",
5549 hostdata->dsa_select, dsa[hostdata->dsa_select / sizeof(u32)]);
5550 cmd = (Scsi_Cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
5551 printk(" + %d : dsa_cmnd = 0x%x ", hostdata->dsa_cmnd,
5552 (u32) virt_to_bus(cmd));
5553
5554 if (cmd) {
5555 printk(" result = 0x%x, target = %d, lun = %d, cmd = ",
5556 cmd->result, cmd->device->id, cmd->device->lun);
5557 print_command(cmd->cmnd);
5558 } else
5559 printk("\n");
5560 printk(" + %d : dsa_next = 0x%x\n", hostdata->dsa_next,
5561 dsa[hostdata->dsa_next / sizeof(u32)]);
5562 if (cmd) {
5563 printk("scsi%d target %d : sxfer_sanity = 0x%x, scntl3_sanity = 0x%x\n"
5564 " script : ",
5565 host->host_no, cmd->device->id,
5566 hostdata->sync[cmd->device->id].sxfer_sanity,
5567 hostdata->sync[cmd->device->id].scntl3_sanity);
5568 for (i = 0; i < (sizeof(hostdata->sync[cmd->device->id].script) / 4); ++i)
5569 printk ("0x%x ", hostdata->sync[cmd->device->id].script[i]);
5570 printk ("\n");
5571 print_progress (cmd);
5572 }
5573}
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583static void
5584print_queues (struct Scsi_Host *host) {
5585 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
5586 host->hostdata[0];
5587 u32 *dsa, *next_dsa;
5588 volatile u32 *ncrcurrent;
5589 int left;
5590 Scsi_Cmnd *cmd, *next_cmd;
5591 unsigned long flags;
5592
5593 printk ("scsi%d : issue queue\n", host->host_no);
5594
5595 for (left<