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