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