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