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