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