This source file includes following definitions.
- internal_setup
- setup_wrapper
- normal_init
- pci_init
- NCR53c7xx_detect
- NCR53c8x0_init_fixup
- NCR53c8xx_run_tests
- NCR53c8xx_dsa_fixup
- abnormal_finished
- intr_break
- 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
- create_cmd
- NCR53c7xx_queue_command
- fix_pointers
- intr_scsi
- NCR53c7x0_intr
- abort_connected
- intr_phase_mismatch
- intr_dma
- print_insn
- NCR53c7xx_abort
- NCR53c7xx_reset
- print_dsa
- shutdown
- halt
- NCR53c7x0_release
1
2
3
4
5
6
7
8
9 #define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1)
10
11
12
13
14
15 #define SCSI_MALLOC
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
66
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 #ifdef MODULE
158 #include <linux/module.h>
159 #endif
160
161 #include <asm/dma.h>
162 #include <asm/io.h>
163 #include <asm/system.h>
164 #include <linux/delay.h>
165 #include <linux/signal.h>
166 #include <linux/sched.h>
167 #include <linux/errno.h>
168 #include <linux/bios32.h>
169 #include <linux/pci.h>
170 #include <linux/string.h>
171 #include <linux/mm.h>
172 #include "../block/blk.h"
173 #include "scsi.h"
174 #include "hosts.h"
175 #include "53c7,8xx.h"
176 #include "constants.h"
177 #include "sd.h"
178
179 static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);
180 static int NCR53c8xx_run_tests (struct Scsi_Host *host);
181 static int NCR53c8xx_script_len;
182 static int NCR53c8xx_dsa_len;
183 static void NCR53c7x0_intr(int irq, struct pt_regs * regs);
184 static int halt (struct Scsi_Host *host);
185 static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd
186 *cmd);
187 static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
188 static void print_dsa (struct Scsi_Host *host, unsigned long *dsa);
189 static int print_insn (struct Scsi_Host *host, unsigned long *insn,
190 char *prefix, int kernel);
191
192 static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd);
193 static void NCR53c8x0_init_fixup (struct Scsi_Host *host);
194 static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
195 NCR53c7x0_cmd *cmd);
196 static void NCR53c8x0_soft_reset (struct Scsi_Host *host);
197
198 static int perm_options = PERM_OPTIONS;
199
200 static struct Scsi_Host *first_host = NULL;
201 static Scsi_Host_Template *the_template = NULL;
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271 struct pci_chip {
272 unsigned short pci_device_id;
273 int chip;
274 int max_revision;
275 int min_revision;
276 };
277
278 static struct pci_chip pci_chip_ids[] = {
279 {PCI_DEVICE_ID_NCR_53C810, 810, 1, 1},
280 {PCI_DEVICE_ID_NCR_53C815, 815, 2, 3},
281 {PCI_DEVICE_ID_NCR_53C820, 820, -1, -1},
282 {PCI_DEVICE_ID_NCR_53C825, 825, -1, -1}
283 };
284
285 #define NPCI_CHIP_IDS (sizeof (pci_chip_ids) / sizeof(pci_chip_ids[0]))
286
287
288
289
290 static struct override {
291 int chip;
292 int board;
293 unsigned pci:1;
294 union {
295 struct {
296 int base;
297 int io_port;
298 int irq;
299 int dma;
300 } normal;
301 struct {
302 int bus;
303 int device;
304 int function;
305 } pci;
306 } data;
307 int options;
308 } overrides [4] = {{0,},};
309 static int commandline_current = 0;
310 static int no_overrides = 0;
311
312 #if 0
313 #define OVERRIDE_LIMIT (sizeof(overrides) / sizeof(struct override))
314 #else
315 #define OVERRIDE_LIMIT commandline_current
316 #endif
317
318
319
320
321
322
323
324
325
326
327
328
329 static void internal_setup(int board, int chip, char *str, int *ints) {
330 unsigned char pci;
331
332
333 pci = (str && !strcmp (str, "pci")) ? 1 : 0;
334
335
336
337
338
339
340
341 if (commandline_current < OVERRIDE_LIMIT) {
342 overrides[commandline_current].pci = pci ? 1 : 0;
343 if (!pci) {
344 overrides[commandline_current].data.normal.base = ints[1];
345 overrides[commandline_current].data.normal.io_port = ints[2];
346 overrides[commandline_current].data.normal.irq = ints[3];
347 overrides[commandline_current].data.normal.dma = (ints[0] >= 4) ?
348 ints[4] : DMA_NONE;
349 overrides[commandline_current].options = (ints[0] >= 5) ?
350 ints[5] : 0;
351 } else {
352 overrides[commandline_current].data.pci.bus = ints[1];
353 overrides[commandline_current].data.pci.device = ints[2];
354 overrides[commandline_current].data.pci.device = ints[3];
355 overrides[commandline_current].options = (ints[0] >= 4) ?
356 ints[4] : 0;
357 }
358 overrides[commandline_current].board = board;
359 overrides[commandline_current].chip = chip;
360 ++commandline_current;
361 ++no_overrides;
362 } else {
363 printk ("53c7,7x0.c:internal_setup() : too many overrides\n");
364 }
365 }
366
367
368
369
370
371
372
373 #define setup_wrapper(x) \
374 void ncr53c##x##_setup (char *str, int *ints) { \
375 internal_setup (BOARD_GENERIC, x, str, ints); \
376 }
377
378 setup_wrapper(700)
379 setup_wrapper(70066)
380 setup_wrapper(710)
381 setup_wrapper(720)
382 setup_wrapper(810)
383 setup_wrapper(815)
384 setup_wrapper(820)
385 setup_wrapper(825)
386
387
388
389
390
391
392
393
394
395
396
397
398 static int
399 NCR53c7x0_init (struct Scsi_Host *host) {
400 NCR53c7x0_local_declare();
401
402 int i, j, ccf;
403 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
404 host->hostdata;
405 struct Scsi_Host *search;
406 NCR53c7x0_local_setup(host);
407
408 switch (hostdata->chip) {
409 case 810:
410 case 815:
411 case 820:
412 case 825:
413 hostdata->dstat_sir_intr = NCR53c8x0_dstat_sir_intr;
414 hostdata->init_save_regs = NULL;
415 hostdata->dsa_fixup = NCR53c8xx_dsa_fixup;
416 hostdata->init_fixup = NCR53c8x0_init_fixup;
417 hostdata->soft_reset = NCR53c8x0_soft_reset;
418 hostdata->run_tests = NCR53c8xx_run_tests;
419
420 hostdata->scsi_clock = 40000000;
421 break;
422 default:
423 printk ("scsi%d : chip type of %d is not supported yet, detaching.\n",
424 host->host_no, hostdata->chip);
425 scsi_unregister (host);
426 return -1;
427 }
428
429
430 hostdata->NCR53c7xx_zero = 0;
431 hostdata->NCR53c7xx_msg_reject = MESSAGE_REJECT;
432 hostdata->NCR53c7xx_msg_abort = ABORT;
433 hostdata->NCR53c7xx_msg_nop = NOP;
434
435
436
437
438
439
440 for (search = first_host; search && ((search->hostt != the_template) ||
441 (search->irq != host->irq)); search=search->next);
442
443 if (!search) {
444 if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx")) {
445 printk("scsi%d : IRQ%d not free, detaching\n",
446 host->host_no, host->irq);
447 scsi_unregister (host);
448 return -1;
449 }
450 } else {
451 printk("scsi%d : using interrupt handler previously installed for scsi%d\n",
452 host->host_no, search->host_no);
453 }
454
455 printk ("scsi%d : using %s mapped access\n", host->host_no,
456 (hostdata->options & OPTION_MEMORY_MAPPED) ? "memory" :
457 "io");
458
459 hostdata->dmode = (hostdata->chip == 700 || hostdata->chip == 70066) ?
460 DMODE_REG_00 : DMODE_REG_10;
461 hostdata->istat = ((hostdata->chip / 100) == 8) ?
462 ISTAT_REG_800 : ISTAT_REG_700;
463
464
465
466 halt(host);
467
468
469
470
471
472
473
474
475
476 #if 0
477 tmp = hostdata->this_id_mask = NCR53c7x0_read8(SCID_REG);
478 for (host->this_id = 0; tmp != 1; tmp >>=1, ++host->this_id);
479 #else
480 host->this_id = NCR53c7x0_read8(SCID_REG) & 7;
481 hostdata->this_id_mask = 1 << host->this_id;
482 #endif
483
484 printk("scsi%d : using initiator ID %d\n", host->host_no,
485 host->this_id);
486
487
488
489
490
491 if ((hostdata->chip / 100) == 8) {
492
493
494
495 hostdata->saved_ctest4 = NCR53c7x0_read8(CTEST4_REG_800) &
496 CTEST4_800_SAVE;
497 } else {
498
499
500
501
502 hostdata->saved_ctest7 = NCR53c7x0_read8(CTEST7_REG) & CTEST7_SAVE;
503 }
504
505
506
507
508
509 hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG);
510
511 if ((hostdata->chip / 100) == 8)
512 printk ("scsi%d : using %s interrupts\n", host->host_no,
513 (hostdata->saved_dcntl & DCNTL_800_IRQM) ? "edge triggered" :
514 "level active");
515
516
517
518
519
520 hostdata->saved_dmode = NCR53c7x0_read8(hostdata->dmode);
521
522
523
524
525
526
527 if ((hostdata->chip / 100) == 8) {
528 if (hostdata->saved_ctest4 & CTEST4_800_BDIS) {
529 printk ("scsi%d : burst mode disabled\n", host->host_no);
530 } else {
531 switch (hostdata->saved_dmode & DMODE_BL_MASK) {
532 case DMODE_BL_2: i = 2; break;
533 case DMODE_BL_4: i = 4; break;
534 case DMODE_BL_8: i = 8; break;
535 case DMODE_BL_16: i = 16; break;
536 default: i = 0;
537 }
538 printk ("scsi%d : burst length %d\n", host->host_no, i);
539 }
540 }
541
542
543
544
545
546 if (hostdata->chip / 100 == 8) {
547 hostdata->saved_scntl3 = NCR53c7x0_read8(SCNTL3_REG_800);
548 ccf = hostdata->saved_scntl3 & SCNTL3_800_CCF_MASK;
549 } else
550 ccf = 0;
551
552
553
554
555
556
557
558
559 if (!hostdata->scsi_clock)
560 switch(ccf) {
561 case 1: hostdata->scsi_clock = 25000000; break;
562 case 2: hostdata->scsi_clock = 37500000; break;
563 case 3: hostdata->scsi_clock = 50000000; break;
564 case 0:
565 case 4: hostdata->scsi_clock = 66000000; break;
566 default:
567 printk ("scsi%d : clock conversion factor %d unknown.\n"
568 " synchronous transfers disabled\n",
569 host->host_no, ccf);
570 hostdata->options &= ~OPTION_SYNCHRONOUS;
571 hostdata->scsi_clock = 0;
572 }
573
574 printk ("scsi%d : using %dMHz SCSI clock\n", host->host_no,
575 hostdata->scsi_clock / 1000000);
576
577
578
579
580
581 for (i = 0; i < 8; ++i) {
582 hostdata->cmd_allocated[i] = 0;
583 for (j = 0; j < 8; ++j)
584 hostdata->busy[i][j] = 0;
585
586
587
588
589
590 if (hostdata->chip != 700 && hostdata->chip != 70066) {
591 hostdata->sync[i].select_indirect |= (i << 16);
592
593 hostdata->sync[i].script[0] = (DCMD_TYPE_TCI|DCMD_TCI_OP_RETURN) << 24 |
594 DBC_TCI_TRUE;
595 switch (hostdata->chip) {
596
597 case 825:
598 case 820:
599
600 case 815:
601 case 810:
602 hostdata->sync[i].select_indirect |= (hostdata->saved_scntl3) << 24;
603 break;
604 default:
605 }
606 }
607 }
608
609 hostdata->issue_queue = hostdata->running_list =
610 hostdata->finished_queue = NULL;
611 hostdata->issue_dsa_head = NULL;
612 hostdata->issue_dsa_tail = NULL;
613
614 if (hostdata->init_save_regs)
615 hostdata->init_save_regs (host);
616 if (hostdata->init_fixup)
617 hostdata->init_fixup (host);
618
619 if (!the_template) {
620 the_template = host->hostt;
621 first_host = host;
622 }
623
624 hostdata->idle = 1;
625
626
627
628
629
630
631
632
633
634
635
636 hostdata->soft_reset (host);
637
638 hostdata->debug_count_limit = -1;
639 hostdata->intrs = -1;
640 hostdata->expecting_iid = 0;
641 hostdata->expecting_sto = 0;
642
643 if ((hostdata->run_tests && hostdata->run_tests(host) == -1) ||
644 (hostdata->options & OPTION_DEBUG_TESTS_ONLY)) {
645
646 scsi_unregister (host);
647 return -1;
648 } else
649 return 0;
650 }
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673 static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
674 int base, int io_port, int irq, int dma, int pci_valid,
675 unsigned char pci_bus, unsigned char pci_device_fn, int options) {
676 struct Scsi_Host *instance;
677 struct NCR53c7x0_hostdata *hostdata;
678 char chip_str[80];
679 int script_len = 0, dsa_len = 0, size = 0, max_cmd_size = 0;
680 int ok = 0;
681
682
683 options |= perm_options;
684
685 switch (chip) {
686 case 825:
687 case 820:
688 case 815:
689 case 810:
690 script_len = NCR53c8xx_script_len;
691 dsa_len = NCR53c8xx_dsa_len;
692 options |= OPTION_INTFLY;
693 sprintf (chip_str, "NCR53c%d", chip);
694 break;
695 default:
696 printk("scsi-ncr53c7,8xx : unsupported SCSI chip %d\n", chip);
697 return -1;
698 }
699
700 printk("scsi-ncr53c7,8xx : %s at memory 0x%x, io 0x%x, irq %d",
701 chip_str, base, io_port, irq);
702 if (dma == DMA_NONE)
703 printk("\n");
704 else
705 printk(", dma %d\n", dma);
706
707 if ((chip / 100 == 8) && !pci_valid)
708 printk ("scsi-ncr53c7,8xx : for better reliability and performance, please use the\n"
709 " PCI override instead.\n"
710 " Syntax : ncr53c8{10,15,20,25}=pci,<bus>,<device>,<function>\n"
711 " <bus> and <device> are usually 0.\n");
712
713 if (options & OPTION_DEBUG_PROBE_ONLY) {
714 printk ("scsi-ncr53c7,8xx : probe only enabled, aborting initialization\n");
715 return -1;
716 }
717
718 max_cmd_size = sizeof(struct NCR53c7x0_cmd) + dsa_len +
719
720 2 *
721 ( 2 *
722 tpnt->sg_tablesize +
723 3
724 ) *
725 8 ;
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751 size = sizeof(struct NCR53c7x0_hostdata) + script_len + max_cmd_size;
752
753 instance = scsi_register (tpnt, size);
754 if (!instance)
755 return -1;
756
757
758
759
760
761
762 hostdata = (struct NCR53c7x0_hostdata *)
763 instance->hostdata;
764 hostdata->size = size;
765 hostdata->script_count = script_len / sizeof(long);
766 hostdata = (struct NCR53c7x0_hostdata *) instance->hostdata;
767 hostdata->board = board;
768 hostdata->chip = chip;
769 if ((hostdata->pci_valid = pci_valid)) {
770 hostdata->pci_bus = pci_bus;
771 hostdata->pci_device_fn = pci_device_fn;
772 }
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788 if (base) {
789 instance->base = (unsigned char *) base;
790
791 if (!(options & OPTION_IO_MAPPED)) {
792 options |= OPTION_MEMORY_MAPPED;
793 ok = 1;
794 }
795 } else {
796 options &= ~OPTION_MEMORY_MAPPED;
797 }
798
799 if (io_port) {
800 instance->io_port = io_port;
801 options |= OPTION_IO_MAPPED;
802 ok = 1;
803 } else {
804 options &= ~OPTION_IO_MAPPED;
805 }
806
807 if (!ok) {
808 printk ("scsi%d : not initializing, no I/O or memory mapping known \n",
809 instance->host_no);
810 scsi_unregister (instance);
811 return -1;
812 }
813 instance->irq = irq;
814 instance->dma_channel = dma;
815
816 hostdata->options = options;
817 hostdata->dsa_size = dsa_len;
818 hostdata->max_cmd_size = max_cmd_size;
819 hostdata->num_cmds = 1;
820
821 hostdata->free = (struct NCR53c7x0_cmd *)
822 (hostdata->script + hostdata->script_count);
823 hostdata->free->real = (void *) hostdata->free;
824 hostdata->free->size = max_cmd_size;
825 hostdata->free->free = NULL;
826 hostdata->free->next = NULL;
827
828
829 return NCR53c7x0_init(instance);
830 }
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854 static int pci_init (Scsi_Host_Template *tpnt, int board, int chip,
855 unsigned char bus, unsigned char device_fn, int options) {
856 unsigned short vendor_id, device_id, command;
857 unsigned long base, io_port;
858 unsigned char irq, revision;
859 int error, expected_chip;
860 int expected_id = -1, max_revision = -1, min_revision = -1;
861 int i;
862
863 printk("scsi-ncr53c7,8xx : at PCI bus %d, device %d, function %d\n",
864 bus, (int) (device_fn & 0xf8) >> 3,
865 (int) device_fn & 7);
866
867 if (!pcibios_present) {
868 printk("scsi-ncr53c7,8xx : not initializing due to lack of PCI BIOS,\n"
869 " try using memory, port, irq override instead.\n");
870 return -1;
871 }
872
873 if ((error = pcibios_read_config_word (bus, device_fn, PCI_VENDOR_ID,
874 &vendor_id)) ||
875 (error = pcibios_read_config_word (bus, device_fn, PCI_DEVICE_ID,
876 &device_id)) ||
877 (error = pcibios_read_config_word (bus, device_fn, PCI_COMMAND,
878 &command)) ||
879 (error = pcibios_read_config_dword (bus, device_fn,
880 PCI_BASE_ADDRESS_0, &io_port)) ||
881 (error = pcibios_read_config_dword (bus, device_fn,
882 PCI_BASE_ADDRESS_1, &base)) ||
883 (error = pcibios_read_config_byte (bus, device_fn, PCI_CLASS_REVISION,
884 &revision)) ||
885 (error = pcibios_read_config_byte (bus, device_fn, PCI_INTERRUPT_LINE,
886 &irq))) {
887 printk ("scsi-ncr53c7,8xx : error %s not initializing due to error reading configuration space\n"
888 " perhaps you specified an incorrect PCI bus, device, or function.\n"
889 , pcibios_strerror(error));
890 return -1;
891 }
892
893
894
895 if (vendor_id != PCI_VENDOR_ID_NCR) {
896 printk ("scsi-ncr53c7,8xx : not initializing, 0x%04x is not NCR vendor ID\n",
897 (int) vendor_id);
898 return -1;
899 }
900
901
902
903
904
905
906
907
908 if (command & PCI_COMMAND_IO) {
909 if ((io_port & 3) != 1) {
910 printk ("scsi-ncr53c7,8xx : disabling I/O mapping since base address 0 (0x%lx)\n"
911 " bits 0..1 indicate a non-IO mapping\n", io_port);
912 io_port = 0;
913 } else
914 io_port &= PCI_BASE_ADDRESS_IO_MASK;
915 } else {
916 io_port = 0;
917 }
918
919 if (command & PCI_COMMAND_MEMORY) {
920 if ((base & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) {
921 printk("scsi-ncr53c7,8xx : disabling memory mapping since base address 1\n"
922 " contains a non-memory mapping\n");
923 base = 0;
924 } else
925 base &= PCI_BASE_ADDRESS_MEM_MASK;
926 } else {
927 base = 0;
928 }
929
930 if (!io_port && !base) {
931 printk ("scsi-ncr53c7,8xx : not initializing, both I/O and memory mappings disabled\n");
932 return -1;
933 }
934
935 if (!(command & PCI_COMMAND_MASTER)) {
936 printk ("scsi-ncr53c7,8xx : not initializing, BUS MASTERING was disabled\n");
937 return -1;
938 }
939
940 for (i = 0; i < NPCI_CHIP_IDS; ++i) {
941 if (device_id == pci_chip_ids[i].pci_device_id) {
942 max_revision = pci_chip_ids[i].max_revision;
943 min_revision = pci_chip_ids[i].min_revision;
944 expected_chip = pci_chip_ids[i].chip;
945 }
946 if (chip == pci_chip_ids[i].chip)
947 expected_id = pci_chip_ids[i].pci_device_id;
948 }
949
950 if (chip && device_id != expected_id)
951 printk ("scsi-ncr53c7,8xx : warning : device id of 0x%04x doesn't\n"
952 " match expected 0x%04x\n",
953 (unsigned int) device_id, (unsigned int) expected_id );
954
955 if (max_revision != -1 && revision > max_revision)
956 printk ("scsi-ncr53c7,8xx : warning : revision of %d is greater than %d.\n",
957 (int) revision, max_revision);
958 else if (min_revision != -1 && revision < min_revision)
959 printk ("scsi-ncr53c7,8xx : warning : revision of %d is less than %d.\n",
960 (int) revision, min_revision);
961
962 return normal_init (tpnt, board, chip, (int) base, (int) io_port,
963 (int) irq, DMA_NONE, 1, bus, device_fn, options);
964 }
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980 int NCR53c7xx_detect(Scsi_Host_Template *tpnt) {
981 int i;
982 int current_override;
983 int count;
984 unsigned char pci_bus, pci_device_fn;
985 static short pci_index=0;
986
987
988 for (current_override = count = 0; current_override < OVERRIDE_LIMIT;
989 ++current_override) {
990 if (overrides[current_override].pci ?
991 !pci_init (tpnt, overrides[current_override].board,
992 overrides[current_override].chip,
993 (unsigned char) overrides[current_override].data.pci.bus,
994 (((overrides[current_override].data.pci.device
995 << 3) & 0xf8)|(overrides[current_override].data.pci.function &
996 7)), overrides[current_override].options):
997 !normal_init (tpnt, overrides[current_override].board,
998 overrides[current_override].chip,
999 overrides[current_override].data.normal.base,
1000 overrides[current_override].data.normal.io_port,
1001 overrides[current_override].data.normal.irq,
1002 overrides[current_override].data.normal.dma,
1003 0 , 0 ,
1004 0 ,
1005 overrides[current_override].options)) {
1006 ++count;
1007 }
1008 }
1009
1010 if (pcibios_present()) {
1011 for (i = 0; i < NPCI_CHIP_IDS; ++i)
1012 for (pci_index = 0;
1013 !pcibios_find_device (PCI_VENDOR_ID_NCR,
1014 pci_chip_ids[i].pci_device_id, pci_index, &pci_bus,
1015 &pci_device_fn) &&
1016 !pci_init (tpnt, BOARD_GENERIC, pci_chip_ids[i].chip,
1017 pci_bus, pci_device_fn, 0);
1018 ++count, ++pci_index);
1019 }
1020 return count;
1021 }
1022
1023
1024
1025 #include "53c8xx_d.h"
1026 static int NCR53c8xx_script_len = sizeof (SCRIPT);
1027 static int NCR53c8xx_dsa_len = A_dsa_end + Ent_dsa_zero - Ent_dsa_code_template;
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038 static void
1039 NCR53c8x0_init_fixup (struct Scsi_Host *host) {
1040 NCR53c7x0_local_declare();
1041 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1042 host->hostdata;
1043 unsigned char tmp;
1044 int i, ncr_to_memory, memory_to_ncr, ncr_to_ncr;
1045 unsigned long base;
1046 NCR53c7x0_local_setup(host);
1047
1048
1049
1050
1051
1052 memcpy ((void *) hostdata->script, (void *) SCRIPT,
1053 sizeof(SCRIPT));
1054
1055 for (i = 0; i < PATCHES; ++i)
1056 hostdata->script[LABELPATCHES[i]] +=
1057 (unsigned long) hostdata->script;
1058
1059
1060 patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_abort,
1061 (long) &(hostdata->NCR53c7xx_msg_abort));
1062 patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_reject,
1063 (long) &(hostdata->NCR53c7xx_msg_reject));
1064 patch_abs_32 (hostdata->script, 0, NCR53c7xx_zero,
1065 (long) &(hostdata->NCR53c7xx_zero));
1066 patch_abs_32 (hostdata->script, 0, NCR53c7xx_sink,
1067 (long) &(hostdata->NCR53c7xx_sink));
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084 tmp = NCR53c7x0_read8(DMODE_REG_10);
1085 tmp &= (DMODE_800_ERL | DMODE_BL_MASK);
1086
1087 if (!(hostdata->options & OPTION_MEMORY_MAPPED)) {
1088 base = (long) host->io_port;
1089 memory_to_ncr = tmp|DMODE_800_DIOM;
1090 ncr_to_memory = tmp|DMODE_800_SIOM;
1091 ncr_to_ncr = tmp|DMODE_800_DIOM|DMODE_800_SIOM;
1092 } else {
1093 base = (long) host->base;
1094 ncr_to_ncr = memory_to_ncr = ncr_to_memory = tmp;
1095 }
1096
1097 patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800);
1098 patch_abs_32 (hostdata->script, 0, addr_sfbr, base + SFBR_REG);
1099 patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG);
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110 patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_memory, tmp);
1111 patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_ncr, memory_to_ncr);
1112 patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory);
1113 patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_ncr, ncr_to_ncr);
1114
1115 patch_abs_32 (hostdata->script, 0, issue_dsa_head,
1116 (long) &(hostdata->issue_dsa_head));
1117 patch_abs_32 (hostdata->script, 0, msg_buf, (long) &(hostdata->msg_buf));
1118 patch_abs_32 (hostdata->script, 0, reconnect_dsa_head,
1119 (long) &(hostdata->reconnect_dsa_head));
1120 patch_abs_32 (hostdata->script, 0, reselected_identify,
1121 (long) &(hostdata->reselected_identify));
1122 patch_abs_32 (hostdata->script, 0, reselected_tag,
1123 (long) &(hostdata->reselected_tag));
1124
1125 patch_abs_32 (hostdata->script, 0, test_dest, (long) &(hostdata->test_dest));
1126 patch_abs_32 (hostdata->script, 0, test_src, (long) &(hostdata->test_source));
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138 hostdata->E_accept_message = Ent_accept_message;
1139 hostdata->E_command_complete = Ent_command_complete;
1140 hostdata->E_debug_break = Ent_debug_break;
1141 hostdata->E_dsa_code_template = Ent_dsa_code_template;
1142 hostdata->E_dsa_code_template_end = Ent_dsa_code_template_end;
1143 hostdata->E_initiator_abort = Ent_initiator_abort;
1144 hostdata->E_msg_in = Ent_msg_in;
1145 hostdata->E_other_transfer = Ent_other_transfer;
1146 hostdata->E_reject_message = Ent_reject_message;
1147 hostdata->E_respond_message = Ent_respond_message;
1148 hostdata->E_schedule = Ent_schedule;
1149 hostdata->E_select = Ent_select;
1150 hostdata->E_select_msgout = Ent_select_msgout;
1151 hostdata->E_target_abort = Ent_target_abort;
1152 #ifdef Ent_test_0
1153 hostdata->E_test_0 = Ent_test_0;
1154 #endif
1155 hostdata->E_test_1 = Ent_test_1;
1156 hostdata->E_test_2 = Ent_test_2;
1157 #ifdef Ent_test_3
1158 hostdata->E_test_3 = Ent_test_3;
1159 #endif
1160
1161 hostdata->dsa_cmdout = A_dsa_cmdout;
1162 hostdata->dsa_cmnd = A_dsa_cmnd;
1163 hostdata->dsa_datain = A_dsa_datain;
1164 hostdata->dsa_dataout = A_dsa_dataout;
1165 hostdata->dsa_end = A_dsa_end;
1166 hostdata->dsa_msgin = A_dsa_msgin;
1167 hostdata->dsa_msgout = A_dsa_msgout;
1168 hostdata->dsa_msgout_other = A_dsa_msgout_other;
1169 hostdata->dsa_next = A_dsa_next;
1170 hostdata->dsa_select = A_dsa_select;
1171 hostdata->dsa_start = Ent_dsa_code_template - Ent_dsa_zero;
1172 hostdata->dsa_status = A_dsa_status;
1173
1174
1175 if (A_dsa_fields_start != Ent_dsa_code_template_end -
1176 Ent_dsa_zero)
1177 printk("scsi%d : NCR dsa_fields start is %d not %d\n",
1178 host->host_no, A_dsa_fields_start, Ent_dsa_code_template_end -
1179 Ent_dsa_zero);
1180
1181 printk("scsi%d : NCR code relocated to 0x%lx\n", host->host_no,
1182 (unsigned long) hostdata->script);
1183 }
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200 static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
1201 NCR53c7x0_local_declare();
1202 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1203 host->hostdata;
1204 unsigned long timeout, start;
1205 int failed, i;
1206 unsigned long flags;
1207
1208 NCR53c7x0_local_setup(host);
1209
1210
1211
1212 save_flags(flags);
1213 cli();
1214 if (!hostdata->idle) {
1215 printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
1216 restore_flags(flags);
1217 return -1;
1218 }
1219
1220
1221
1222
1223
1224
1225 if (hostdata->issue_dsa_head) {
1226 printk ("scsi%d : hostdata->issue_dsa_head corrupt before test 1\n",
1227 host->host_no);
1228 hostdata->issue_dsa_head = NULL;
1229 }
1230
1231 if (hostdata->options & OPTION_DEBUG_TEST1) {
1232 hostdata->idle = 0;
1233 hostdata->test_running = 1;
1234 hostdata->test_completed = -1;
1235 hostdata->test_dest = 0;
1236 hostdata->test_source = 0xdeadbeef;
1237 start = ((unsigned long) hostdata->script) + hostdata->E_test_1;
1238 hostdata->state = STATE_RUNNING;
1239 printk ("scsi%d : test 1", host->host_no);
1240 NCR53c7x0_write32 (DSP_REG, start);
1241 printk (" started\n");
1242 sti();
1243
1244 timeout = jiffies + 50;
1245 while ((hostdata->test_completed == -1) && jiffies < timeout);
1246
1247 failed = 1;
1248 if (hostdata->test_completed == -1)
1249 printk ("scsi%d : driver test 1 timed out%s\n",host->host_no ,
1250 (hostdata->test_dest == 0xdeadbeef) ?
1251 " due to lost interrupt.\n"
1252 " Please verify that the correct IRQ is being used for your board,\n"
1253 " and that the motherboard IRQ jumpering matches the PCI setup on\n"
1254 " PCI systems.\n"
1255 " If you are using a NCR53c810 board in a PCI system, you should\n"
1256 " also verify that the board is jumpered to use PCI INTA, since\n"
1257 " most PCI motherboards lack support for INTB, INTC, and INTD.\n"
1258 : "");
1259 else if (hostdata->test_completed != 1)
1260 printk ("scsi%d : test 1 bad interrupt value (%ld)\n", host->host_no,
1261 hostdata->test_completed);
1262 else
1263 failed = (hostdata->test_dest != 0xdeadbeef);
1264
1265 if (hostdata->test_dest != 0xdeadbeef) {
1266 printk ("scsi%d : driver test 1 read 0x%x instead of 0xdeadbeef indicating a\n"
1267 " probable cache invalidation problem. Please configure caching\n"
1268 " as write-through or disabled\n",
1269 host->host_no, hostdata->test_dest);
1270 }
1271
1272 if (failed) {
1273 printk ("scsi%d : DSP = 0x%lx (script at 0x%lx, start at 0x%lx)\n",
1274 host->host_no, (unsigned long) NCR53c7x0_read32(DSP_REG),
1275 (unsigned long) hostdata->script, start);
1276 printk ("scsi%d : DSPS = 0x%lx\n", host->host_no,
1277 (unsigned long) NCR53c7x0_read32(DSPS_REG));
1278 restore_flags(flags);
1279 return -1;
1280 }
1281 hostdata->test_running = 0;
1282 }
1283
1284 if (hostdata->issue_dsa_head) {
1285 printk ("scsi%d : hostdata->issue_dsa_head corrupt after test 1\n",
1286 host->host_no);
1287 hostdata->issue_dsa_head = NULL;
1288 }
1289
1290 if (hostdata->options & OPTION_DEBUG_TEST2) {
1291 unsigned long dsa[48];
1292 unsigned char identify = IDENTIFY(0, 0);
1293 unsigned char cmd[6];
1294 unsigned char data[36];
1295 unsigned char status = 0xff;
1296 unsigned char msg = 0xff;
1297
1298 cmd[0] = INQUIRY;
1299 cmd[1] = cmd[2] = cmd[3] = cmd[5] = 0;
1300 cmd[4] = sizeof(data);
1301
1302 dsa[2] = 1;
1303 dsa[3] = (unsigned long) &identify;
1304 dsa[4] = 6;
1305 dsa[5] = (unsigned long) &cmd;
1306 dsa[6] = sizeof(data);
1307 dsa[7] = (unsigned long) &data;
1308 dsa[8] = 1;
1309 dsa[9] = (unsigned long) &status;
1310 dsa[10] = 1;
1311 dsa[11] = (unsigned long) &msg;
1312
1313 for (i = 0; i < 3; ++i) {
1314 cli();
1315 if (!hostdata->idle) {
1316 printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
1317 restore_flags(flags);
1318 return -1;
1319 }
1320
1321
1322 dsa[0] = (0x33 << 24) | (i << 16) ;
1323 hostdata->idle = 0;
1324 hostdata->test_running = 2;
1325 hostdata->test_completed = -1;
1326 start = ((unsigned long) hostdata->script) + hostdata->E_test_2;
1327 hostdata->state = STATE_RUNNING;
1328 NCR53c7x0_write32 (DSA_REG, (unsigned long) dsa);
1329 NCR53c7x0_write32 (DSP_REG, start);
1330 sti();
1331
1332 timeout = jiffies + 500;
1333 while ((hostdata->test_completed == -1) && jiffies < timeout);
1334 NCR53c7x0_write32 (DSA_REG, 0);
1335
1336 if (hostdata->test_completed == 2) {
1337 data[35] = 0;
1338 printk ("scsi%d : test 2 INQUIRY to target %d, lun 0 : %s\n",
1339 host->host_no, i, data + 8);
1340 printk ("scsi%d : status ", host->host_no);
1341 print_status (status);
1342 printk ("\nscsi%d : message ", host->host_no);
1343 print_msg (&msg);
1344 printk ("\n");
1345 } else if (hostdata->test_completed == 3) {
1346 printk("scsi%d : test 2 no connection with target %d\n",
1347 host->host_no, i);
1348 if (!hostdata->idle) {
1349 printk("scsi%d : not idle\n", host->host_no);
1350 restore_flags(flags);
1351 return -1;
1352 }
1353 } else if (hostdata->test_completed == -1) {
1354 printk ("scsi%d : test 2 timed out\n", host->host_no);
1355 restore_flags(flags);
1356 return -1;
1357 }
1358 hostdata->test_running = 0;
1359 if (hostdata->issue_dsa_head) {
1360 printk ("scsi%d : hostdata->issue_dsa_head corrupt after test 2 id %d\n",
1361 host->host_no, i);
1362 hostdata->issue_dsa_head = NULL;
1363 }
1364 }
1365 }
1366
1367 restore_flags(flags);
1368 return 0;
1369 }
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381 static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
1382 Scsi_Cmnd *c = cmd->cmd;
1383 struct Scsi_Host *host = c->host;
1384 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1385 host->hostdata;
1386 int i;
1387
1388 memcpy (cmd->dsa, hostdata->script + (hostdata->E_dsa_code_template / 4),
1389 hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template);
1390
1391 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1392 dsa_temp_jump_resume, ((unsigned long) cmd->dsa) +
1393 Ent_dsa_jump_resume - Ent_dsa_zero);
1394 patch_abs_rwri_data (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1395 dsa_temp_lun, c->lun);
1396 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1397 dsa_temp_dsa_next, ((unsigned long) cmd->dsa) + A_dsa_next);
1398 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1399 dsa_temp_sync, hostdata->sync[c->target].select_indirect);
1400 patch_abs_rwri_data (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1401 dsa_temp_target, c->target);
1402 }
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419 static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
1420 Scsi_Cmnd *c = cmd->cmd;
1421 struct Scsi_Host *host = c->host;
1422 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1423 host->hostdata;
1424 unsigned long flags;
1425 char **prev, *search;
1426 int i;
1427
1428 save_flags(flags);
1429 cli();
1430 for (i = 0; i < 2; ++i) {
1431 for (search = (char *) (i ? hostdata->issue_dsa_head :
1432 hostdata->reconnect_dsa_head), prev = (char **) (i ?
1433 &(hostdata->issue_dsa_head) : &(hostdata->reconnect_dsa_head));
1434 search && (search + hostdata->dsa_start) != (char *) cmd->dsa;
1435 prev = (char **) (search + hostdata->dsa_next),
1436 search = *prev);
1437
1438 if (search)
1439 *prev = *(char **) (search + hostdata->dsa_next);
1440 }
1441
1442 if (cmd->prev)
1443 cmd->prev->next = cmd->next;
1444
1445 if (cmd->next)
1446 cmd->next->prev = cmd->prev;
1447
1448 if (hostdata->running_list == cmd)
1449 hostdata->running_list = cmd->next;
1450
1451 cmd->next = hostdata->free;
1452 hostdata->free = cmd;
1453
1454 c->host_scribble = NULL;
1455 c->result = result;
1456 c->scsi_done(c);
1457
1458 restore_flags(flags);
1459 }
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473 static void intr_break (struct Scsi_Host *host, struct
1474 NCR53c7x0_cmd *cmd) {
1475 NCR53c7x0_local_declare();
1476 struct NCR53c7x0_break *bp;
1477 #if 0
1478 Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
1479 #endif
1480 unsigned long *dsp;
1481 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1482 host->hostdata;
1483 unsigned long flags;
1484 NCR53c7x0_local_setup(host);
1485
1486
1487
1488
1489
1490
1491 save_flags(flags);
1492 cli();
1493 dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
1494 for (bp = hostdata->breakpoints; bp && bp->address != dsp;
1495 bp = bp->next);
1496 if (!bp)
1497 panic("scsi%d : break point interrupt from %p with no breakpoint!",
1498 host->host_no, dsp);
1499
1500
1501
1502
1503
1504
1505
1506 NCR53c7x0_write8 (hostdata->dmode,
1507 NCR53c7x0_read8(hostdata->dmode)|DMODE_MAN);
1508
1509
1510
1511
1512
1513
1514 restore_flags(flags);
1515 }
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528 static int asynchronous (struct Scsi_Host *host, int target) {
1529 NCR53c7x0_local_declare();
1530 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1531 host->hostdata;
1532 NCR53c7x0_local_setup(host);
1533
1534 if ((hostdata->chip / 100) == 8) {
1535 hostdata->sync[target].select_indirect = (hostdata->saved_scntl3 << 24)
1536 | (target << 16);
1537
1538 } else if ((hostdata->chip != 700) && (hostdata->chip != 70066)) {
1539 hostdata->sync[target].select_indirect = (1 << (target & 7)) << 16;
1540 }
1541
1542
1543
1544
1545
1546
1547 if (hostdata->state == STATE_HALTED) {
1548 if ((hostdata->chip / 100) == 8) {
1549 NCR53c7x0_write8 (SCNTL3_REG_800, hostdata->saved_scntl3);
1550 }
1551
1552 NCR53c7x0_write8 (SXFER_REG, 0);
1553 }
1554 return 0;
1555 }
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565 static const struct {
1566 int div;
1567 unsigned char scf;
1568 unsigned char tp;
1569 } syncs[] = {
1570
1571 { 40, 1, 0}, { 50, 1, 1}, { 60, 1, 2},
1572 { 70, 1, 3}, { 75, 2, 1}, { 80, 1, 4},
1573 { 90, 1, 5}, { 100, 1, 6}, { 105, 2, 3},
1574 { 110, 1, 7}, { 120, 2, 4}, { 135, 2, 5},
1575 { 140, 3, 3}, { 150, 2, 6}, { 160, 3, 4},
1576 { 165, 2, 7}, { 180, 3, 5}, { 200, 3, 6},
1577 { 210, 4, 3}, { 220, 3, 7}, { 240, 4, 4},
1578 { 270, 4, 5}, { 300, 4, 6}, { 330, 4, 7}
1579 };
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596 static void synchronous (struct Scsi_Host *host, int target, char *msg) {
1597 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1598 host->hostdata;
1599 int desire, divisor, i, limit;
1600 unsigned long *script;
1601 unsigned char scntl3, sxfer;
1602
1603
1604 desire = 1000000000L / (msg[3] * 4);
1605 divisor = desire / (hostdata->scsi_clock / 10);
1606
1607 if (msg[4] > 8)
1608 msg[4] = 8;
1609
1610 printk("scsi%d : optimal synchronous divisor of %d.%01d\n", host->host_no,
1611 divisor / 10, divisor % 10);
1612
1613 limit = (sizeof(syncs) / sizeof(syncs[0])) - 1;
1614 for (i = 0; (i < limit) && (divisor < syncs[i + 1].div); ++i);
1615
1616 printk("scsi%d : selected synchronous divisor of %d.%01d\n", host->host_no,
1617 syncs[i].div / 10, syncs[i].div % 10);
1618
1619 msg[3] = (1000000000 / divisor / 10 / 4);
1620
1621 scntl3 = (hostdata->chip / 100 == 8) ? ((hostdata->saved_scntl3 &
1622 ~SCNTL3_800_SCF_MASK) | (syncs[i].scf << SCNTL3_800_SCF_SHIFT)) : 0;
1623 sxfer = (msg[4] << SXFER_MO_SHIFT) | ((syncs[i].tp) << SXFER_TP_SHIFT);
1624
1625 if ((hostdata->chip != 700) && (hostdata->chip != 70066)) {
1626 hostdata->sync[target].select_indirect = (scntl3 << 24) | (target << 16) |
1627 (sxfer << 8);
1628
1629 script = (long *) hostdata->sync[target].script;
1630
1631
1632 if ((hostdata->chip / 100) == 8) {
1633 script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
1634 DCMD_RWRI_OP_MOVE) << 24) |
1635 (SCNTL3_REG_800 << 16) | (scntl3 << 8);
1636 script[1] = 0;
1637 script += 2;
1638 }
1639
1640 script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
1641 DCMD_RWRI_OP_MOVE) << 24) |
1642 (SXFER_REG << 16) | (sxfer << 8);
1643 script[1] = 0;
1644 script += 2;
1645
1646 script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_RETURN) << 24) | DBC_TCI_TRUE;
1647 script[1] = 0;
1648 script += 2;
1649 }
1650 }
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665 static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
1666 NCR53c7x0_cmd *cmd) {
1667 NCR53c7x0_local_declare();
1668 Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
1669 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1670 host->hostdata;
1671 unsigned long dsps,*dsp;
1672 NCR53c7x0_local_setup(host);
1673 dsps = NCR53c7x0_read32(DSPS_REG);
1674 dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
1675
1676 if (hostdata->options & OPTION_DEBUG_INTR)
1677 printk ("scsi%d : DSPS = 0x%lx\n", host->host_no, dsps);
1678
1679 switch (dsps) {
1680 case A_int_msg_1:
1681 printk ("scsi%d : message", host->host_no);
1682 if (cmd)
1683 printk (" from target %d lun %d", c->target, c->lun);
1684 print_msg ((unsigned char *) hostdata->msg_buf);
1685 printk("\n");
1686 switch (hostdata->msg_buf[0]) {
1687
1688
1689
1690
1691 case MESSAGE_REJECT:
1692 hostdata->dsp = hostdata->script + hostdata->E_accept_message /
1693 sizeof(long);
1694 hostdata->dsp_changed = 1;
1695 break;
1696 case INITIATE_RECOVERY:
1697 printk ("scsi%d : extended contingent allegiance not supported yet, rejecting\n",
1698 host->host_no);
1699 hostdata->dsp = hostdata->script + hostdata->E_reject_message /
1700 sizeof(long);
1701 hostdata->dsp_changed = 1;
1702 }
1703 return SPECIFIC_INT_NOTHING;
1704 case A_int_msg_sdtr:
1705 if (cmd) {
1706 printk ("scsi%d : target %d %s synchronous transfer period %dns, offset%d\n",
1707 host->host_no, c->target, (cmd->flags & CMD_FLAG_SDTR) ? "accepting" :
1708 "requesting", hostdata->msg_buf[3] * 4, hostdata->msg_buf[4]);
1709
1710
1711
1712
1713
1714
1715
1716
1717 if (cmd->flags & CMD_FLAG_SDTR) {
1718 cmd->flags &= ~CMD_FLAG_SDTR;
1719 synchronous (host, c->target, (unsigned char *)
1720 hostdata->msg_buf);
1721 hostdata->dsp = hostdata->script + hostdata->E_accept_message /
1722 sizeof(long);
1723 hostdata->dsp_changed = 1;
1724 return SPECIFIC_INT_NOTHING;
1725 } else {
1726 if (hostdata->options & OPTION_SYNCHRONOUS) {
1727 cmd->flags |= CMD_FLAG_DID_SDTR;
1728 synchronous (host, c->target, (unsigned char *)
1729 hostdata->msg_buf);
1730 } else {
1731 hostdata->msg_buf[4] = 0;
1732 }
1733
1734 patch_dsa_32 (cmd->dsa, dsa_msgout_other, 0, 5);
1735 patch_dsa_32 (cmd->dsa, dsa_msgout_other, 1,
1736 hostdata->msg_buf);
1737 hostdata->dsp = hostdata->script +
1738 hostdata->E_respond_message / sizeof(long);
1739 hostdata->dsp_changed = 1;
1740 }
1741
1742 if (hostdata->msg_buf[4]) {
1743 int Hz = 1000000000 / (hostdata->msg_buf[3] * 4);
1744 printk ("scsi%d : setting target %d to %d.%02dMhz %s SCSI%s\n"
1745 " period = %dns, max offset = %d\n",
1746 host->host_no, c->target, Hz / 1000000, Hz % 1000000,
1747 ((hostdata->msg_buf[3] < 200) ? "FAST " :
1748 "synchronous") ,
1749 ((hostdata->msg_buf[3] < 200) ? "-II" : ""),
1750 (int) hostdata->msg_buf[3] * 4, (int)
1751 hostdata->msg_buf[4]);
1752 } else {
1753 printk ("scsi%d : setting target %d to asynchronous SCSI\n",
1754 host->host_no, c->target);
1755 }
1756 return SPECIFIC_INT_NOTHING;
1757 }
1758
1759 case A_int_msg_wdtr:
1760 hostdata->dsp = hostdata->script + hostdata->E_reject_message /
1761 sizeof(long);
1762 hostdata->dsp_changed = 1;
1763 return SPECIFIC_INT_NOTHING;
1764 case A_int_err_unexpected_phase:
1765 if (hostdata->options & OPTION_DEBUG_INTR)
1766 printk ("scsi%d : unexpected phase\n", host->host_no);
1767 return SPECIFIC_INT_ABORT;
1768 case A_int_err_selected:
1769 printk ("scsi%d : selected by target %d\n", host->host_no,
1770 (int) NCR53c7x0_read8(SSID_REG_800) &7);
1771 hostdata->dsp = hostdata->script + hostdata->E_target_abort /
1772 sizeof(long);
1773 hostdata->dsp_changed = 1;
1774 return SPECIFIC_INT_NOTHING;
1775 case A_int_err_unexpected_reselect:
1776 printk ("scsi%d : unexpected reselect by target %d\n", host->host_no,
1777 (int) NCR53c7x0_read8(SSID_REG_800));
1778 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
1779 sizeof(long);
1780 hostdata->dsp_changed = 1;
1781 return SPECIFIC_INT_NOTHING;
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791 case A_int_err_check_condition:
1792 #if 0
1793 if (hostdata->options & OPTION_DEBUG_INTR)
1794 #endif
1795 printk ("scsi%d : CHECK CONDITION\n", host->host_no);
1796 if (!c) {
1797 printk("scsi%d : CHECK CONDITION with no SCSI command\n",
1798 host->host_no);
1799 return SPECIFIC_INT_PANIC;
1800 }
1801
1802
1803
1804
1805
1806
1807 asynchronous (host, c->target);
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819 patch_dsa_32 (cmd->dsa, dsa_msgout, 0, 1);
1820
1821
1822
1823
1824
1825
1826 patch_dsa_32 (cmd->dsa, dsa_cmdout, 0, 6);
1827
1828 c->cmnd[0] = REQUEST_SENSE;
1829 c->cmnd[1] &= 0xe0;
1830 c->cmnd[2] = 0;
1831 c->cmnd[3] = 0;
1832 c->cmnd[4] = sizeof(c->sense_buffer);
1833 c->cmnd[5] = 0;
1834
1835
1836
1837
1838
1839
1840
1841 patch_dsa_32 (cmd->dsa, dsa_dataout, 0, hostdata->E_other_transfer);
1842 patch_dsa_32 (cmd->dsa, dsa_datain, 0, cmd->data_transfer_start);
1843 cmd->data_transfer_start[0] = (((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I |
1844 DCMD_BMI_IO)) << 24) | sizeof(c->sense_buffer);
1845 cmd->data_transfer_start[1] = (unsigned long) c->sense_buffer;
1846
1847 cmd->data_transfer_start[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP)
1848 << 24) | DBC_TCI_TRUE;
1849 cmd->data_transfer_start[3] = hostdata->E_other_transfer;
1850
1851
1852
1853
1854
1855
1856
1857
1858 cmd->cmd->result = 0xffff;
1859
1860
1861
1862
1863 hostdata->dsp = hostdata->script + hostdata->E_select /
1864 sizeof(long);
1865 hostdata->dsp_changed = 1;
1866 return SPECIFIC_INT_NOTHING;
1867 case A_int_debug_break:
1868 return SPECIFIC_INT_BREAK;
1869 case A_int_norm_aborted:
1870 hostdata->dsp = hostdata->script + hostdata->E_schedule /
1871 sizeof(long);
1872 hostdata->dsp_changed = 1;
1873 if (cmd)
1874 abnormal_finished (cmd, DID_ERROR << 16);
1875 return SPECIFIC_INT_NOTHING;
1876 case A_int_test_1:
1877 case A_int_test_2:
1878 hostdata->idle = 1;
1879 hostdata->test_completed = (dsps - A_int_test_1) / 0x00010000 + 1;
1880 if (hostdata->options & OPTION_DEBUG_INTR)
1881 printk("scsi%d : test%ld complete\n", host->host_no,
1882 hostdata->test_completed);
1883 return SPECIFIC_INT_NOTHING;
1884 #ifdef A_int_debug_scheduled
1885 case A_int_debug_scheduled:
1886 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1887 printk("scsi%d : new I/O 0x%lx scheduled\n", host->host_no,
1888 NCR53c7x0_read32(DSA_REG));
1889 }
1890 return SPECIFIC_INT_RESTART;
1891 #endif
1892 #ifdef A_int_debug_idle
1893 case A_int_debug_idle:
1894 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1895 printk("scsi%d : idle\n", host->host_no);
1896 }
1897 return SPECIFIC_INT_RESTART;
1898 #endif
1899 #ifdef A_int_debug_cmd
1900 case A_int_debug_cmd:
1901 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1902 printk("scsi%d : command sent\n");
1903 }
1904 return SPECIFIC_INT_RESTART;
1905 #endif
1906 #ifdef A_int_debug_dsa_loaded
1907 case A_int_debug_dsa_loaded:
1908 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1909 printk("scsi%d : DSA loaded with 0x%lx\n", host->host_no,
1910 NCR53c7x0_read32(DSA_REG));
1911 }
1912 return SPECIFIC_INT_RESTART;
1913 #endif
1914 #ifdef A_int_debug_reselected
1915 case A_int_debug_reselected:
1916 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1917 printk("scsi%d : reselected by target %d lun %d\n",
1918 host->host_no, (int) NCR53c7x0_read8(SSID_REG_800),
1919 (int) hostdata->reselected_identify & 7);
1920 }
1921 return SPECIFIC_INT_RESTART;
1922 #endif
1923 #ifdef A_int_debug_head
1924 case A_int_debug_head:
1925 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1926 printk("scsi%d : issue_dsa_head now 0x%lx\n",
1927 host->host_no, (unsigned long) hostdata->issue_dsa_head);
1928 }
1929 return SPECIFIC_INT_RESTART;
1930 #endif
1931 default:
1932 if ((dsps & 0xff000000) == 0x03000000) {
1933 printk ("scsi%d : misc debug interrupt 0x%lx\n",
1934 host->host_no, dsps);
1935 return SPECIFIC_INT_RESTART;
1936 }
1937
1938 printk ("scsi%d : unknown user interrupt 0x%x\n",
1939 host->host_no, (unsigned) dsps);
1940 return SPECIFIC_INT_PANIC;
1941 }
1942 }
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958 #include "53c8xx_u.h"
1959
1960
1961
1962
1963 #ifdef NCR_DEBUG
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978 static const char debugger_help =
1979 "bc <addr> - clear breakpoint\n"
1980 "bl - list breakpoints\n"
1981 "bs <addr> - set breakpoint\n"
1982 "g - start\n"
1983 "h - halt\n"
1984 "? - this message\n"
1985 "i - info\n"
1986 "mp <addr> <size> - print memory\n"
1987 "ms <addr> <size> <value> - store memory\n"
1988 "rp <num> <size> - print register\n"
1989 "rs <num> <size> <value> - store register\n"
1990 "s - single step\n"
1991 "tb - begin trace \n"
1992 "te - end trace\n";
1993
1994
1995
1996
1997
1998
1999 static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token,
2000 unsigned long args[]) {
2001 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2002 instance->hostdata;
2003 struct NCR53c7x0_break *bp, **prev;
2004 unsigned long flags;
2005 save_flags(flags);
2006 cli();
2007 for (bp = (struct NCR53c7x0_break *) instance->breakpoints,
2008 prev = (struct NCR53c7x0_break **) &instance->breakpoints;
2009 bp; prev = (struct NCR53c7x0_break **) &(bp->next),
2010 bp = (struct NCR53c7x0_break *) bp->next);
2011
2012 if (!bp) {
2013 restore_flags(flags);
2014 return -EIO;
2015 }
2016
2017
2018
2019
2020
2021
2022 memcpy ((void *) bp->addr, (void *) bp->old, sizeof(bp->old));
2023 if (prev)
2024 *prev = bp->next;
2025
2026 restore_flags(flags);
2027 return 0;
2028 }
2029
2030
2031 static int debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token,
2032 unsigned long args[]) {
2033 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2034 host->hostdata;
2035 struct NCR53c7x0_break *bp;
2036 char buf[80];
2037 size_t len;
2038 unsigned long flags;
2039
2040
2041
2042
2043
2044
2045 sprintf (buf, "scsi%d : bp : warning : processor not halted\b",
2046 host->host_no);
2047 debugger_kernel_write (host, buf, strlen(buf));
2048
2049 save_flags(flags);
2050 cli();
2051 for (bp = (struct NCR53c7x0_break *) host->breakpoints;
2052 bp; bp = (struct NCR53c7x0_break *) bp->next); {
2053 sprintf (buf, "scsi%d : bp : success : at %08x, replaces %08x %08x",
2054 bp->addr, bp->old[0], bp->old[1]);
2055 len = strlen(buf);
2056 if ((bp->old[0] & (DCMD_TYPE_MASK << 24)) ==
2057 (DCMD_TYPE_MMI << 24)) {
2058 sprintf(buf + len, "%08x\n", * (long *) bp->addr);
2059 } else {
2060 sprintf(buf + len, "\n");
2061 }
2062 len = strlen(buf);
2063 debugger_kernel_write (host, buf, len);
2064 }
2065 restore_flags(flags);
2066 return 0;
2067 }
2068
2069 static int debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token,
2070 unsigned long args[]) {
2071 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2072 host->hostdata;
2073 struct NCR53c7x0_break *bp;
2074 char buf[80];
2075 size_t len;
2076 unsigned long flags;
2077 save_flags(flags);
2078 cli();
2079
2080 if (hostdata->state != STATE_HALTED) {
2081 sprintf (buf, "scsi%d : bs : failure : NCR not halted\n", host->host_no);
2082 debugger_kernel_write (host, buf, strlen(buf));
2083 restore_flags(flags);
2084 return -1;
2085 }
2086
2087 if (!(bp = kmalloc (sizeof (struct NCR53c7x0_break)))) {
2088 printk ("scsi%d : kmalloc(%d) of breakpoint structure failed, try again\n",
2089 host->host_no, sizeof(struct NCR53c7x0_break));
2090 restore_flags(flags);
2091 return -1;
2092 }
2093
2094 bp->address = (unsigned long *) args[0];
2095 memcpy ((void *) bp->old_instruction, (void *) bp->address, 8);
2096 bp->old_size = (((bp->old_instruction[0] >> 24) & DCMD_TYPE_MASK) ==
2097 DCMD_TYPE_MMI ? 3 : 2;
2098 bp->next = hostdata->breakpoints;
2099 hostdata->breakpoints = bp->next;
2100 memcpy ((void *) bp->address, (void *) hostdata->E_debug_break, 8);
2101
2102 restore_flags(flags);
2103 return 0;
2104 }
2105
2106 #define TOKEN(name,nargs) {#name, nargs, debugger_fn_##name}
2107 static const struct debugger_token {
2108 char *name;
2109 int numargs;
2110 int (*fn)(struct debugger_token *token, unsigned long args[]);
2111 } debugger_tokens[] = {
2112 TOKEN(bc,1), TOKEN(bl,0), TOKEN(bs,1), TOKEN(g,0), TOKEN(halt,0),
2113 {DT_help, "?", 0} , TOKEN(h,0), TOKEN(i,0), TOKEN(mp,2),
2114 TOKEN(ms,3), TOKEN(rp,2), TOKEN(rs,2), TOKEN(s,0), TOKEN(tb,0), TOKEN(te,0)
2115 };
2116
2117 #define NDT sizeof(debugger_tokens / sizeof(struct debugger_token))
2118
2119 static struct Scsi_Host * inode_to_host (struct inode *inode) {$
2120 int dev;
2121 struct Scsi_Host *tmp;
2122 for (dev = MINOR(inode->rdev), host = first_host;
2123 (host->hostt == the_template); --dev, host = host->next)
2124 if (!dev) return host;
2125 return NULL;
2126 }
2127
2128
2129 static debugger_user_write (struct inode *inode,struct file *filp,
2130 char *buf,int count) {
2131 struct Scsi_Host *host;
2132 struct NCR53c7x0_hostadata *hostdata;
2133 char input_buf[80],
2134 *ptr;
2135 unsigned long args[3];
2136 int i, j, error, len;
2137
2138 if (!(host = inode_to_host(inode)))
2139 return -ENXIO;
2140
2141 hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
2142
2143 if (error = verify_area(VERIFY_READ,buf,count))
2144 return error;
2145
2146 if (count > 80)
2147 return -EIO;
2148
2149 memcpy_from_fs(input_buf, buf, count);
2150
2151 if (input_buf[count - 1] != '\n')
2152 return -EIO;
2153
2154 input_buf[count - 1]=0;
2155
2156 for (i = 0; i < NDT; ++i) {
2157 len = strlen (debugger_tokens[i].name);
2158 if (!strncmp(input_buf, debugger_tokens[i].name, len))
2159 break;
2160 };
2161
2162 if (i == NDT)
2163 return -EIO;
2164
2165 for (ptr = input_buf + len, j = 0; j < debugger_tokens[i].nargs && *ptr;) {
2166 if (*ptr == ' ' || *ptr == '\t') {
2167 ++ptr;
2168 } else if (isdigit(*ptr)) {
2169 args[j++] = simple_strtoul (ptr, &ptr, 0);
2170 } else {
2171 return -EIO;
2172 }
2173 }
2174
2175 if (j != debugger_tokens[i].nargs)
2176 return -EIO;
2177
2178 return count;
2179 }
2180
2181 static debugger_user_read (struct inode *inode,struct file *filp,
2182 char *buf,int count) {
2183 struct Scsi_Host *instance;
2184
2185 }
2186
2187 static debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t
2188 buflen) {
2189 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2190 host->hostdata;
2191 int copy, left;
2192 unsigned long flags;
2193 save_flags(flags);
2194 cli();
2195 while (buflen) {
2196 left = (hostdata->debug_buf + hostdata->debug_size - 1) -
2197 hostdata->debug_write;
2198 copy = (buflen <= left) ? buflen : left;
2199 memcpy (hostdata->debug_write, buf, copy);
2200 buf += copy;
2201 buflen -= copy;
2202 hostdata->debug_count += copy;
2203 if ((hostdata->debug_write += copy) ==
2204 (hostdata->debug_buf + hostdata->debug_size))
2205 hosdata->debug_write = hostdata->debug_buf;
2206 }
2207 restore_flags(flags);
2208 }
2209
2210 #endif
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224 static void
2225 NCR53c8x0_soft_reset (struct Scsi_Host *host) {
2226 NCR53c7x0_local_declare();
2227 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2228 host->hostdata;
2229 NCR53c7x0_local_setup(host);
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242 NCR53c7x0_write8(ISTAT_REG_800, ISTAT_10_SRST);
2243 NCR53c7x0_write8(ISTAT_REG_800, 0);
2244 NCR53c7x0_write8(hostdata->dmode, hostdata->saved_dmode & ~DMODE_MAN);
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255 #ifdef notyet
2256 NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE|SCID_800_SRE);
2257 #else
2258 NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE);
2259 #endif
2260 NCR53c7x0_write8(RESPID_REG_800, hostdata->this_id_mask);
2261
2262
2263
2264
2265
2266
2267 NCR53c7x0_write8(STIME0_REG_800,
2268 ((14 << STIME0_800_SEL_SHIFT) & STIME0_800_SEL_MASK)
2269
2270 #if 0
2271 | ((15 << STIME0_800_HTH_SHIFT) & STIME0_800_HTH_MASK)
2272 #endif
2273 );
2274
2275
2276
2277
2278
2279
2280
2281
2282 NCR53c7x0_write8(DIEN_REG, DIEN_800_MDPE | DIEN_800_BF |
2283 DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_800_IID);
2284
2285
2286 NCR53c7x0_write8(SIEN0_REG_800, ((hostdata->options & OPTION_PARITY) ?
2287 SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
2288 NCR53c7x0_write8(SIEN1_REG_800, SIEN1_800_STO | SIEN1_800_HTH);
2289
2290
2291
2292
2293
2294
2295 NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl);
2296 NCR53c7x0_write8(CTEST4_REG_800, hostdata->saved_ctest4);
2297
2298
2299 NCR53c7x0_write8(STEST3_REG_800, STEST3_800_TE);
2300
2301
2302 }
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321 static struct NCR53c7x0_cmd *
2322 create_cmd (Scsi_Cmnd *cmd) {
2323 NCR53c7x0_local_declare();
2324 struct Scsi_Host *host = cmd->host;
2325 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2326 host->hostdata;
2327 struct NCR53c7x0_cmd *tmp = NULL;
2328 int datain,
2329 dataout;
2330 int data_transfer_instructions,
2331 i;
2332 unsigned long *cmd_datain,
2333 *cmd_dataout;
2334 #ifdef notyet
2335 void *real;
2336 int size;
2337 int alignment;
2338 #endif
2339 unsigned long flags;
2340 NCR53c7x0_local_setup(cmd->host);
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351 #ifdef notyet
2352
2353 if (hostdata->num_commands < host->can_queue &&
2354 !in_scan_scsis &&
2355 !(hostdata->cmd_allocated[cmd->target] & (1 << cmd->lun))) {
2356 for (i = host->hostt->cmd_per_lun - 1; i >= 0 --i) {
2357 #ifdef SCSI_MALLOC
2358
2359
2360 size = (hostdata->max_cmd_size + 511) / 512 * 512;
2361 tmp = (struct NCR53c7x0_cmd *) scsi_malloc (size);
2362 if (!tmp)
2363 break;
2364 tmp->real = (void *) tmp;
2365 #else
2366
2367
2368 size = hostdata->max_cmd_size + 4;
2369 real = kmalloc (size, GFP_ATOMIC);
2370 alignment = 4 - (((unsigned) real) & 3);
2371 tmp = (struct NCR53c7x0_cmd *) (((char *) real) + alignment);
2372 if (!tmp)
2373 break;
2374 tmp->real = real;
2375 #endif
2376 tmp->size = size;
2377
2378 if (i > 0) {
2379 tmp->next = hostdata->free;
2380 hostdata->free = tmp;
2381 }
2382 }
2383 }
2384 #endif
2385 if (!tmp) {
2386 save_flags(flags);
2387 cli();
2388 tmp = (struct NCR53c7x0_cmd *) hostdata->free;
2389 if (tmp) {
2390 hostdata->free = tmp->next;
2391 restore_flags(flags);
2392 } else {
2393 restore_flags(flags);
2394 return NULL;
2395 }
2396 }
2397
2398
2399
2400
2401
2402
2403
2404 switch (cmd->cmnd[0]) {
2405
2406 case INQUIRY:
2407 case MODE_SENSE:
2408 case READ_6:
2409 case READ_10:
2410 case READ_CAPACITY:
2411 case REQUEST_SENSE:
2412 datain = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
2413 dataout = 0;
2414 break;
2415
2416 case MODE_SELECT:
2417 case WRITE_6:
2418 case WRITE_10:
2419 #if 0
2420 printk("scsi%d : command is ", host->host_no);
2421 print_command(cmd->cmnd);
2422 #endif
2423 #if 0
2424 printk ("scsi%d : %d scatter/gather segments\n", host->host_no,
2425 cmd->use_sg);
2426 #endif
2427 datain = 0;
2428 dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
2429 #if 0
2430 hostdata->options |= OPTION_DEBUG_INTR;
2431 #endif
2432 break;
2433
2434
2435
2436
2437 case START_STOP:
2438 case TEST_UNIT_READY:
2439 datain = dataout = 0;
2440 break;
2441
2442
2443
2444
2445 default:
2446 datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
2447 }
2448
2449
2450
2451
2452
2453
2454
2455 data_transfer_instructions = datain + dataout;
2456
2457
2458
2459
2460
2461
2462
2463 if (data_transfer_instructions < 2)
2464 data_transfer_instructions = 2;
2465
2466
2467
2468
2469
2470
2471 tmp->cmd = cmd;
2472 tmp->next = NULL;
2473 tmp->prev = NULL;
2474
2475
2476
2477
2478
2479 tmp->data_transfer_start = tmp->dsa + (hostdata->dsa_end -
2480 hostdata->dsa_start) / sizeof(long);
2481 tmp->data_transfer_end = tmp->data_transfer_start +
2482 2 * data_transfer_instructions;
2483
2484 cmd_datain = datain ? tmp->data_transfer_start : NULL;
2485 cmd_dataout = dataout ? (datain ? cmd_datain + 2 * datain : tmp->
2486 data_transfer_start) : NULL;
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496 if (hostdata->dsa_fixup)
2497 hostdata->dsa_fixup(tmp);
2498
2499 patch_dsa_32(tmp->dsa, dsa_next, 0, NULL);
2500 patch_dsa_32(tmp->dsa, dsa_cmnd, 0, cmd);
2501 patch_dsa_32(tmp->dsa, dsa_select, 0, hostdata->sync[cmd->target].
2502 select_indirect);
2503
2504
2505
2506
2507 patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
2508 #if 0
2509 tmp->select[0] = IDENTIFY (1, cmd->lun);
2510 #else
2511 tmp->select[0] = IDENTIFY (0, cmd->lun);
2512 #endif
2513 patch_dsa_32(tmp->dsa, dsa_msgout, 1, tmp->select);
2514 patch_dsa_32(tmp->dsa, dsa_cmdout, 0, cmd->cmd_len);
2515 patch_dsa_32(tmp->dsa, dsa_cmdout, 1, cmd->cmnd);
2516 patch_dsa_32(tmp->dsa, dsa_dataout, 0, cmd_dataout ?
2517 cmd_dataout : hostdata->script + hostdata->E_other_transfer /
2518 sizeof (long));
2519 patch_dsa_32(tmp->dsa, dsa_datain, 0, cmd_datain ?
2520 cmd_datain : hostdata->script + hostdata->E_other_transfer /
2521 sizeof (long));
2522
2523
2524
2525
2526 patch_dsa_32(tmp->dsa, dsa_msgin, 0, 1);
2527 patch_dsa_32(tmp->dsa, dsa_msgin, 1, (((unsigned long) &cmd->result) + 1));
2528 patch_dsa_32(tmp->dsa, dsa_status, 0, 1);
2529 patch_dsa_32(tmp->dsa, dsa_status, 1, &cmd->result);
2530 patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, 1);
2531 patch_dsa_32(tmp->dsa, dsa_msgout_other, 1,
2532 &(hostdata->NCR53c7xx_msg_nop));
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547 #if 0
2548 if (datain) {
2549 cmd_datain[0] = 0x98080000;
2550 cmd_datain[1] = 0x03ffd00d;
2551 cmd_datain += 2;
2552 }
2553 #endif
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570 for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4,
2571 cmd_dataout += 4, ++i) {
2572 unsigned long buf = (unsigned long) (cmd->use_sg ?
2573 ((struct scatterlist *)cmd->buffer)[i].address :
2574 cmd->request_buffer);
2575 unsigned long count = (unsigned long) (cmd->use_sg ?
2576 ((struct scatterlist *)cmd->buffer)[i].length :
2577 cmd->request_bufflen);
2578
2579 if (datain) {
2580 cmd_datain[0] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | DCMD_BMI_IO)
2581 << 24) | count;
2582 cmd_datain[1] = buf;
2583 cmd_datain[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
2584 DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) |
2585 DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE;
2586 cmd_datain[3] = (unsigned long) hostdata->script +
2587 hostdata->E_msg_in;
2588 #if 0
2589 print_insn (host, cmd_datain, "dynamic ", 1);
2590 print_insn (host, cmd_datain + 2, "dynamic ", 1);
2591 #endif
2592 }
2593 if (dataout) {
2594 cmd_dataout[0] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I) << 24)
2595 | count;
2596 cmd_dataout[1] = buf;
2597 cmd_dataout[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
2598 DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) |
2599 DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE;
2600 cmd_dataout[3] = (unsigned long) hostdata->script +
2601 hostdata->E_msg_in;
2602 #if 0
2603 print_insn (host, cmd_dataout, "dynamic ", 1);
2604 print_insn (host, cmd_dataout + 2, "dynamic ", 1);
2605 #endif
2606 }
2607 }
2608
2609
2610
2611
2612
2613
2614
2615 if (datain) {
2616 cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
2617 DBC_TCI_TRUE;
2618 cmd_datain[1] = (unsigned long) hostdata->script +
2619 hostdata->E_other_transfer;
2620 #if 0
2621 print_insn (host, cmd_datain, "dynamic jump ", 1);
2622 #endif
2623 cmd_datain += 2;
2624 }
2625 #if 0
2626 if (datain) {
2627 cmd_datain[0] = 0x98080000;
2628 cmd_datain[1] = 0x03ffdeed;
2629 cmd_datain += 2;
2630 }
2631 #endif
2632
2633
2634 if (dataout) {
2635 cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
2636 DBC_TCI_TRUE;
2637 cmd_dataout[1] = (unsigned long) hostdata->script +
2638 hostdata->E_other_transfer;
2639 #if 0
2640 print_insn (host, cmd_dataout, "dynamic jump ", 1);
2641 #endif
2642 cmd_dataout += 2;
2643 }
2644
2645
2646 return tmp;
2647 }
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667 int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
2668 NCR53c7x0_local_declare();
2669 struct NCR53c7x0_cmd *tmp;
2670 struct Scsi_Host *host = cmd->host;
2671 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2672 host->hostdata;
2673 unsigned long flags;
2674 unsigned char target_was_busy;
2675 NCR53c7x0_local_setup(host);
2676
2677 if (((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY)) ||
2678 ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
2679 !(hostdata->debug_lun_limit[cmd->target] & (1 << cmd->lun)))) ||
2680 cmd->target > 7) {
2681 printk("scsi%d : disabled target %d lun %d\n", host->host_no,
2682 cmd->target, cmd->lun);
2683 cmd->result = (DID_BAD_TARGET << 16);
2684 done(cmd);
2685 return 0;
2686 }
2687
2688 if (hostdata->options & OPTION_DEBUG_NCOMMANDS_LIMIT) {
2689 if (hostdata->debug_count_limit == 0) {
2690 printk("scsi%d : maximum commands exceeded\n", host->host_no);
2691 cmd->result = (DID_BAD_TARGET << 16);
2692 done(cmd);
2693 return 0;
2694 } else if (hostdata->debug_count_limit != -1)
2695 --hostdata->debug_count_limit;
2696 }
2697
2698 if (hostdata->options & OPTION_DEBUG_READ_ONLY) {
2699 switch (cmd->cmnd[0]) {
2700 case WRITE_6:
2701 case WRITE_10:
2702 printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
2703 host->host_no);
2704 cmd->result = (DID_BAD_TARGET << 16);
2705 done(cmd);
2706 return 0;
2707 }
2708 }
2709
2710 cmd->scsi_done = done;
2711 cmd->result = 0xffff;
2712
2713
2714 cmd->host_scribble = (unsigned char *) tmp = create_cmd (cmd);
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741 save_flags(flags);
2742 cli();
2743
2744
2745
2746
2747
2748
2749
2750
2751 target_was_busy = hostdata->busy[cmd->target][cmd->lun]
2752 #ifdef LUN_BUSY
2753 ++
2754 #endif
2755 ;
2756
2757 if (!(hostdata->options & OPTION_700) &&
2758 !target_was_busy) {
2759 unsigned char *dsa = ((unsigned char *) tmp->dsa)
2760 - hostdata->dsa_start;
2761
2762 #if 0
2763 printk("scsi%d : new dsa is 0x%x\n", host->host_no, (unsigned) dsa);
2764 #endif
2765
2766 if (hostdata->running_list)
2767 hostdata->running_list->prev = tmp;
2768
2769 tmp->next = hostdata->running_list;
2770
2771 if (!hostdata->running_list)
2772 hostdata->running_list = tmp;
2773
2774
2775 if (hostdata->idle) {
2776 hostdata->idle = 0;
2777 hostdata->state = STATE_RUNNING;
2778 NCR53c7x0_write32 (DSP_REG, ((unsigned long) hostdata->script) +
2779 hostdata->E_schedule);
2780 }
2781
2782
2783 for (;;) {
2784
2785
2786
2787
2788
2789
2790 if (!hostdata->issue_dsa_head) {
2791 #if 0
2792 printk ("scsi%d : no issue queue\n", host->host_no);
2793 #endif
2794 hostdata->issue_dsa_tail = hostdata->issue_dsa_head = dsa;
2795 NCR53c7x0_write8(hostdata->istat,
2796 NCR53c7x0_read8(hostdata->istat) | ISTAT_10_SIGP);
2797 break;
2798
2799
2800
2801
2802
2803
2804
2805 } else {
2806 printk ("scsi%d : existing issue queue\n", host->host_no);
2807
2808 hostdata->issue_dsa_tail = *((unsigned char **)
2809 (hostdata->issue_dsa_tail + hostdata->dsa_next)) = dsa;
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821 if (hostdata->issue_dsa_head)
2822 break;
2823 }
2824 }
2825
2826 } else {
2827 #if 1
2828 printk ("scsi%d : using issue_queue instead of issue_dsa_head!\n",
2829 host->host_no);
2830 #endif
2831 for (tmp = (struct NCR53c7x0_cmd *) hostdata->issue_queue;
2832 tmp->next; tmp = (struct NCR53c7x0_cmd *) tmp->next);
2833 tmp->next = tmp;
2834 }
2835 restore_flags(flags);
2836 return 0;
2837 }
2838
2839
2840 int fix_pointers (unsigned long dsa) {
2841 return 0;
2842 }
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855 static void intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
2856 NCR53c7x0_local_declare();
2857 struct NCR53c7x0_hostdata *hostdata =
2858 (struct NCR53c7x0_hostdata *) host->hostdata;
2859 unsigned char sstat0_sist0, sist1,
2860 fatal;
2861
2862 NCR53c7x0_local_setup(host);
2863
2864 fatal = 0;
2865
2866 if ((hostdata->chip / 100) == 8) {
2867 sstat0_sist0 = NCR53c7x0_read8(SIST0_REG_800);
2868 udelay(1);
2869 sist1 = NCR53c7x0_read8(SIST1_REG_800);
2870 } else {
2871 sstat0_sist0 = NCR53c7x0_read8(SSTAT0_REG);
2872 sist1 = 0;
2873 }
2874
2875 if (hostdata->options & OPTION_DEBUG_INTR)
2876 printk ("scsi%d : SIST0 0x%0x, SIST1 0x%0x\n", host->host_no,
2877 sstat0_sist0, sist1);
2878
2879
2880 if ((((hostdata->chip / 100) == 8) && (sist1 & SIST1_800_STO)) ||
2881 (((hostdata->chip / 100) != 8) && (sstat0_sist0 & SSTAT0_700_STO))) {
2882 fatal = 1;
2883 if (hostdata->options & OPTION_DEBUG_INTR) {
2884 printk ("scsi%d : Selection Timeout\n", host->host_no);
2885 if (cmd) {
2886 printk("scsi%d : target %d, lun %d, command ",
2887 host->host_no, cmd->cmd->target, cmd->cmd->lun);
2888 print_command (cmd->cmd->cmnd);
2889 printk("scsi%d : dsp = 0x%x\n", host->host_no,
2890 (unsigned) NCR53c7x0_read32(DSP_REG));
2891 } else {
2892 printk("scsi%d : no command\n", host->host_no);
2893 }
2894 }
2895
2896
2897
2898
2899
2900
2901 if (1) {
2902 hostdata->idle = 1;
2903 hostdata->expecting_sto = 0;
2904
2905 if (hostdata->test_running) {
2906 hostdata->test_running = 0;
2907 hostdata->test_completed = 3;
2908 } else if (cmd) {
2909 abnormal_finished(cmd, DID_BAD_TARGET << 16);
2910 }
2911 #if 0
2912 hostdata->intrs = 0;
2913 #endif
2914 }
2915 }
2916
2917 if (sstat0_sist0 & SSTAT0_UDC) {
2918 fatal = 1;
2919 if (cmd) {
2920 printk("scsi%d : target %d lun %d unexpected disconnect\n",
2921 host->host_no, cmd->cmd->target, cmd->cmd->lun);
2922 abnormal_finished(cmd, DID_ERROR << 16);
2923 }
2924 hostdata->dsp = hostdata->script + hostdata->E_schedule /
2925 sizeof(long);
2926 hostdata->dsp_changed = 1;
2927
2928 }
2929
2930 if (sstat0_sist0 & SSTAT0_PAR) {
2931 fatal = 1;
2932 if (cmd && cmd->cmd) {
2933 printk("scsi%d : target %d lun %d parity error.\n",
2934 host->host_no, cmd->cmd->target, cmd->cmd->lun);
2935 abnormal_finished (cmd, DID_PARITY << 16);
2936 } else
2937 printk("scsi%d : parity error\n", host->host_no);
2938
2939
2940
2941 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
2942 sizeof(long);
2943 hostdata->dsp_changed = 1;
2944
2945 }
2946
2947 if (sstat0_sist0 & SSTAT0_SGE) {
2948 fatal = 1;
2949 printk("scsi%d : gross error\n", host->host_no);
2950
2951 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
2952 sizeof(long);
2953 hostdata->dsp_changed = 1;
2954
2955 }
2956
2957 if (sstat0_sist0 & SSTAT0_MA) {
2958 fatal = 1;
2959 if (hostdata->options & OPTION_DEBUG_INTR)
2960 printk ("scsi%d : SSTAT0_MA\n", host->host_no);
2961 intr_phase_mismatch (host, cmd);
2962 }
2963
2964 #if 1
2965
2966
2967
2968
2969
2970 if (fatal) {
2971 if (!hostdata->dstat_valid) {
2972 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
2973 hostdata->dstat_valid = 1;
2974 }
2975
2976
2977 if (!(hostdata->dstat & DSTAT_DFE)) {
2978 printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
2979 #if 0
2980 if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
2981 NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
2982 while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
2983 DSTAT_DFE));
2984 } else
2985 #endif
2986 {
2987 NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
2988 while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
2989 }
2990 }
2991
2992 NCR53c7x0_write8 (STEST3_REG_800, STEST3_800_CSF);
2993 while (NCR53c7x0_read8 (STEST3_REG_800) & STEST3_800_CSF);
2994 }
2995 #endif
2996 }
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009 static void NCR53c7x0_intr (int irq, struct pt_regs * regs) {
3010 NCR53c7x0_local_declare();
3011 struct Scsi_Host *host;
3012 unsigned char istat;
3013 struct NCR53c7x0_hostdata *hostdata;
3014 struct NCR53c7x0_cmd *cmd,
3015 **cmd_prev_ptr;
3016 unsigned long *dsa;
3017 int done = 1;
3018
3019 int interrupted = 0;
3020
3021 unsigned long flags;
3022
3023 #ifdef NCR_DEBUG
3024 char buf[80];
3025 size_t buflen;
3026 #endif
3027
3028 #if 0
3029 printk("interrupt %d received\n", irq);
3030 #endif
3031
3032 do {
3033 done = 1;
3034 for (host = first_host; host; host = hostdata->next ?
3035 hostdata->next : NULL) {
3036 NCR53c7x0_local_setup(host);
3037
3038 hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
3039 hostdata->dsp_changed = 0;
3040 interrupted = 0;
3041
3042
3043 do {
3044 hostdata->dstat_valid = 0;
3045 interrupted = 0;
3046
3047
3048
3049
3050 istat = NCR53c7x0_read8(hostdata->istat);
3051
3052
3053
3054
3055
3056
3057
3058
3059 if ((hostdata->options & OPTION_INTFLY) &&
3060 ((hostdata->chip / 100) == 8 && (istat & ISTAT_800_INTF))) {
3061 char search_found = 0;
3062 done = 0;
3063 interrupted = 1;
3064
3065
3066
3067
3068
3069 NCR53c7x0_write8(hostdata->istat, istat|ISTAT_800_INTF);
3070
3071 if (hostdata->options & OPTION_DEBUG_INTR)
3072 printk ("scsi%d : INTFLY\n", host->host_no);
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082 save_flags(flags);
3083 cli();
3084 restart:
3085 for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)
3086 &(hostdata->running_list), cmd =
3087 (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
3088 cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next),
3089 cmd = (struct NCR53c7x0_cmd *) cmd->next) {
3090 Scsi_Cmnd *tmp;
3091
3092 if (!cmd) {
3093 printk("scsi%d : very weird.\n", host->host_no);
3094 break;
3095 }
3096
3097 if (!(tmp = cmd->cmd)) {
3098 printk("scsi%d : weird. NCR53c7x0_cmd has no Scsi_Cmnd\n",
3099 host->host_no);
3100 continue;
3101 }
3102 #if 0
3103 printk ("scsi%d : looking at result of 0x%x\n",
3104 host->host_no, cmd->cmd->result);
3105 #endif
3106
3107 if (((tmp->result & 0xff) == 0xff) ||
3108 ((tmp->result & 0xff00) == 0xff00))
3109 continue;
3110
3111 search_found = 1;
3112
3113
3114
3115 if (cmd->prev)
3116 cmd->prev->next = cmd->next;
3117 if (cmd_prev_ptr)
3118 *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next;
3119
3120 #ifdef LUN_BUSY
3121
3122 if (--hostdata->busy[tmp->target][tmp->lun]) {
3123 }
3124 #endif
3125
3126
3127 cmd->next = hostdata->free;
3128 hostdata->free = cmd;
3129
3130 tmp->host_scribble = NULL;
3131
3132 if (hostdata->options & OPTION_DEBUG_INTR) {
3133 printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 0x%x ",
3134 host->host_no, tmp->pid, tmp->target, tmp->lun, tmp->result);
3135 print_command (tmp->cmnd);
3136 }
3137
3138
3139 #if 0
3140 hostdata->options &= ~OPTION_DEBUG_INTR;
3141 #endif
3142 tmp->scsi_done(tmp);
3143 goto restart;
3144
3145 }
3146 restore_flags(flags);
3147
3148 if (!search_found) {
3149 printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
3150 host->host_no);
3151 }
3152 }
3153
3154 if (istat & (ISTAT_SIP|ISTAT_DIP)) {
3155 done = 0;
3156 interrupted = 1;
3157 hostdata->state = STATE_HALTED;
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168 if (hostdata->options & OPTION_700) {
3169 cmd = (struct NCR53c7x0_cmd *) hostdata->current;
3170 } else {
3171 dsa = (unsigned long *) NCR53c7x0_read32(DSA_REG);
3172 for (cmd = (struct NCR53c7x0_cmd *)
3173 hostdata->running_list; cmd &&
3174 (dsa + (hostdata->dsa_start / sizeof(long))) !=
3175 cmd->dsa;
3176 cmd = (struct NCR53c7x0_cmd *)(cmd->next));
3177 }
3178 if (hostdata->options & OPTION_DEBUG_INTR) {
3179 if (cmd) {
3180 printk("scsi%d : interrupt for pid %lu, id %d, lun %d ",
3181 host->host_no, cmd->cmd->pid, (int) cmd->cmd->target,
3182 (int) cmd->cmd->lun);
3183 print_command (cmd->cmd->cmnd);
3184 } else {
3185 printk("scsi%d : no active command\n", host->host_no);
3186 }
3187 }
3188
3189 if (istat & ISTAT_SIP) {
3190 if (hostdata->options & OPTION_DEBUG_INTR)
3191 printk ("scsi%d : ISTAT_SIP\n", host->host_no);
3192 intr_scsi (host, cmd);
3193 }
3194
3195 if (istat & ISTAT_DIP) {
3196 if (hostdata->options & OPTION_DEBUG_INTR)
3197 printk ("scsi%d : ISTAT_DIP\n", host->host_no);
3198 intr_dma (host, cmd);
3199 }
3200
3201 if (!hostdata->dstat_valid) {
3202 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
3203 hostdata->dstat_valid = 1;
3204 }
3205
3206 #if 1
3207
3208 if (!(hostdata->dstat & DSTAT_DFE)) {
3209 printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
3210 #if 0
3211 if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
3212 NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
3213 while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
3214 DSTAT_DFE));
3215 } else
3216 #endif
3217 {
3218 NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
3219 while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
3220 }
3221 }
3222 #endif
3223 }
3224 } while (interrupted);
3225
3226
3227
3228 if (hostdata->intrs != -1)
3229 hostdata->intrs++;
3230 #if 0
3231 if (hostdata->intrs > 4) {
3232 printk("scsi%d : too many interrupts, halting", host->host_no);
3233 hostdata->idle = 1;
3234 hostdata->options |= OPTION_DEBUG_INIT_ONLY;
3235 panic("dying...\n");
3236 }
3237 #endif
3238
3239 if (!hostdata->idle && hostdata->state == STATE_HALTED) {
3240 if (!hostdata->dsp_changed) {
3241 hostdata->dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
3242 }
3243
3244 #if 0
3245 printk("scsi%d : new dsp is 0x%lx\n", host->host_no,
3246 (long) hostdata->dsp);
3247 #endif
3248
3249 hostdata->state = STATE_RUNNING;
3250 NCR53c7x0_write32 (DSP_REG, (unsigned long) hostdata->dsp);
3251 }
3252 }
3253 } while (!done);
3254 }
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269 static int
3270 abort_connected (struct Scsi_Host *host) {
3271 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3272 host->hostdata;
3273
3274 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
3275 sizeof(long);
3276 hostdata->dsp_changed = 1;
3277 printk ("scsi%d : DANGER : abort_connected() called \n",
3278 host->host_no);
3279
3280
3281
3282 return 0;
3283 }
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302 static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd
3303 *cmd) {
3304 NCR53c7x0_local_declare();
3305 unsigned long dbc_dcmd, *dsp, *dsp_next;
3306 unsigned char dcmd, sbcl;
3307 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3308 host->hostdata;
3309 char *phase;
3310 NCR53c7x0_local_setup(host);
3311
3312 if (!cmd) {
3313 printk ("scsi%d : phase mismatch interrupt occurred with no current command.\n",
3314 host->host_no);
3315 abort_connected(host);
3316 return;
3317 }
3318
3319
3320
3321
3322
3323
3324 dsp_next = (unsigned long *) NCR53c7x0_read32(DSP_REG);
3325
3326
3327
3328
3329
3330
3331
3332 dbc_dcmd = NCR53c7x0_read32(DBC_REG);
3333 dcmd = (dbc_dcmd & 0xff000000) >> 24;
3334 dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
3335
3336
3337
3338
3339
3340
3341
3342 sbcl = NCR53c7x0_read8(SBCL_REG);
3343 switch (sbcl) {
3344 case SBCL_PHASE_DATAIN:
3345 phase = "DATAIN";
3346 break;
3347 case SBCL_PHASE_DATAOUT:
3348 phase = "DATAOUT";
3349 break;
3350 case SBCL_PHASE_MSGIN:
3351 phase = "MSGIN";
3352 break;
3353 case SBCL_PHASE_MSGOUT:
3354 phase = "MSGOUT";
3355 break;
3356 case SBCL_PHASE_CMDOUT:
3357 phase = "CMDOUT";
3358 break;
3359 case SBCL_PHASE_STATIN:
3360 phase = "STATUSIN";
3361 break;
3362 default:
3363 phase = "unknown";
3364 break;
3365 }
3366
3367
3368
3369
3370
3371
3372
3373 if (dsp >= cmd->data_transfer_start & dsp < cmd->data_transfer_end) {
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383 switch (sbcl & SBCL_PHASE_MASK) {
3384
3385
3386
3387
3388 case SBCL_PHASE_STATIN:
3389 if (hostdata->options & OPTION_DEBUG_INTR)
3390 printk ("scsi%d : new phase = STATIN\n", host->host_no);
3391 hostdata->dsp = hostdata->script + hostdata->E_command_complete /
3392 sizeof(long);
3393 hostdata->dsp_changed = 1;
3394 return;
3395
3396
3397
3398
3399
3400
3401
3402 case SBCL_PHASE_MSGIN:
3403 if (hostdata->options & OPTION_DEBUG_INTR)
3404 printk ("scsi%d : new phase = MSGIN\n", host->host_no);
3405 if ((dcmd & (DCMD_TYPE_MASK|DCMD_BMI_OP_MASK|DCMD_BMI_INDIRECT|
3406 DCMD_BMI_MSG|DCMD_BMI_CD)) == (DCMD_TYPE_BMI|
3407 DCMD_BMI_OP_MOVE_I)) {
3408 dsp[0] = dbc_dcmd;
3409 dsp[1] = NCR53c7x0_read32(DNAD_REG);
3410 NCR53c7x0_write32(TEMP_REG, (unsigned long) dsp);
3411 hostdata->dsp = hostdata->script + hostdata->E_msg_in /
3412 sizeof(long);
3413 hostdata->dsp_changed = 1;
3414 } else {
3415 printk("scsi%d : unexpected MSGIN in dynamic NCR code, dcmd=0x%x.\n",
3416 host->host_no, dcmd);
3417 print_insn (host, dsp, "", 1);
3418 print_insn (host, dsp_next, "", 1);
3419 abort_connected (host);
3420 }
3421 return;
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432 default:
3433 printk ("scsi%d : unexpected phase %s in data routine\n",
3434 host->host_no, phase);
3435 abort_connected(host);
3436 }
3437
3438
3439
3440 } else {
3441 printk ("scsi%d : unexpected phase %s at dsp = 0x%x\n",
3442 host->host_no, phase, (unsigned) dsp);
3443 print_insn (host, dsp, "", 1);
3444 print_insn (host, dsp_next, "", 1);
3445 abort_connected(host);
3446 }
3447 }
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460 static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
3461 NCR53c7x0_local_declare();
3462 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3463 host->hostdata;
3464 unsigned char dstat;
3465 unsigned long *dsp,
3466 *next_dsp,
3467 *dsa,
3468 dbc_dcmd;
3469 int tmp;
3470 unsigned long flags;
3471 NCR53c7x0_local_setup(host);
3472
3473 if (!hostdata->dstat_valid) {
3474 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
3475 hostdata->dstat_valid = 1;
3476 }
3477
3478 dstat = hostdata->dstat;
3479
3480 if (hostdata->options & OPTION_DEBUG_INTR)
3481 printk("scsi%d : DSTAT=0x%x\n", host->host_no, (int) dstat);
3482
3483 dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
3484 next_dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
3485 dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
3486
3487 dsa = (unsigned long *) NCR53c7x0_read32(DSA_REG);
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500 if (dstat & DSTAT_ABRT) {
3501 #if 0
3502
3503 if ((hostdata->options & OPTION_700) && (hostdata->state ==
3504 STATE_ABORTING) {
3505 } else
3506 #endif
3507 {
3508 printk("scsi%d : unexpected abort interrupt at\n"
3509 " ", host->host_no);
3510 print_insn (host, dsp, "s ", 1);
3511 panic(" ");
3512 }
3513 }
3514
3515
3516
3517
3518
3519
3520 if (dstat & DSTAT_SSI) {
3521 if (hostdata->options & OPTION_DEBUG_TRACE) {
3522 } else if (hostdata->options & OPTION_DEBUG_SINGLE) {
3523 print_insn (host, dsp, "s ", 0);
3524 save_flags(flags);
3525 cli();
3526
3527
3528 NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) &
3529 ~DCNTL_SSM) | DCNTL_STD);
3530 restore_flags(flags);
3531 } else {
3532 printk("scsi%d : unexpected single step interrupt at\n"
3533 " ", host->host_no);
3534 print_insn (host, dsp, "", 1);
3535 panic(" mail drew@colorad.edu\n");
3536 }
3537 }
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549 if (dstat & DSTAT_OPC) {
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562 if (((dsp >= (hostdata->script + hostdata->E_select / sizeof(long))) &&
3563 (dsp <= (hostdata->script + hostdata->E_select_msgout /
3564 sizeof(long) + 8))) || (hostdata->test_running == 2)) {
3565 if (hostdata->options & OPTION_DEBUG_INTR)
3566 printk ("scsi%d : ignoring DSTAT_IID for SSTAT_STO\n",
3567 host->host_no);
3568 if (hostdata->expecting_iid) {
3569 hostdata->expecting_iid = 0;
3570 hostdata->idle = 1;
3571 if (hostdata->test_running == 2) {
3572 hostdata->test_running = 0;
3573 hostdata->test_completed = 3;
3574 } else if (cmd)
3575 abnormal_finished (cmd, DID_BAD_TARGET << 16);
3576 } else {
3577 hostdata->expecting_sto = 1;
3578 }
3579 } else {
3580 printk("scsi%d : illegal instruction ", host->host_no);
3581 print_insn (host, dsp, "", 1);
3582 printk("scsi%d : DSP=0x%lx, DCMD|DBC=0x%lx, DSA=0x%lx\n"
3583 " DSPS=0x%lx, TEMP=0x%lx, DMODE=0x%x,\n"
3584 " DNAD=0x%lx\n",
3585 host->host_no, (unsigned long) dsp, dbc_dcmd,
3586 (unsigned long) dsa, NCR53c7x0_read32(DSPS_REG),
3587 NCR53c7x0_read32(TEMP_REG), (int) NCR53c7x0_read8(hostdata->dmode),
3588 NCR53c7x0_read32(DNAD_REG));
3589 panic(" mail drew@Colorado.EDU\n");
3590 }
3591 }
3592
3593
3594
3595
3596
3597
3598 if (dstat & DSTAT_800_BF) {
3599 printk("scsi%d : BUS FAULT, DSP=0x%lx, DCMD|DBC=0x%lx, DSA=0x%lx\n"
3600 " DSPS=0x%lx, TEMP=0x%lx, DMODE=0x%x\n",
3601 host->host_no, (unsigned long) dsp, NCR53c7x0_read32(DBC_REG),
3602 (unsigned long) dsa, NCR53c7x0_read32(DSPS_REG),
3603 NCR53c7x0_read32(TEMP_REG), (int) NCR53c7x0_read8(hostdata->dmode));
3604 print_dsa (host, dsa);
3605 printk("scsi%d : DSP->\n", host->host_no);
3606 print_insn(host, dsp, "", 1);
3607 print_insn(host, next_dsp, "", 1);
3608 #if 0
3609 panic(" mail drew@Colorado.EDU\n");
3610 #else
3611 hostdata->idle = 1;
3612 hostdata->options |= OPTION_DEBUG_INIT_ONLY;
3613 #endif
3614 }
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625 if (dstat & DSTAT_SIR) {
3626 if (hostdata->options & OPTION_DEBUG_INTR)
3627 printk ("scsi%d : DSTAT_SIR\n", host->host_no);
3628 switch ((tmp = hostdata->dstat_sir_intr (host, cmd))) {
3629 case SPECIFIC_INT_NOTHING:
3630 case SPECIFIC_INT_RESTART:
3631 break;
3632 case SPECIFIC_INT_ABORT:
3633 abort_connected(host);
3634 break;
3635 case SPECIFIC_INT_PANIC:
3636 printk("scsi%d : failure at ", host->host_no);
3637 print_insn (host, dsp, "", 1);
3638 panic(" dstat_sir_intr() returned SPECIFIC_INT_PANIC\n");
3639 break;
3640 case SPECIFIC_INT_BREAK:
3641 intr_break (host, cmd);
3642 break;
3643 default:
3644 printk("scsi%d : failure at ", host->host_no);
3645 print_insn (host, dsp, "", 1);
3646 panic(" dstat_sir_intr() returned unknown value %d\n",
3647 tmp);
3648 }
3649 }
3650
3651
3652 NCR53c7x0_write8 (STEST3_REG_800, STEST3_800_CSF);
3653 while (NCR53c7x0_read8 (STEST3_REG_800) & STEST3_800_CSF);
3654 }
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673 static int print_insn (struct Scsi_Host *host, unsigned long *insn,
3674 char *prefix, int kernel) {
3675 char buf[80],
3676 *tmp;
3677 unsigned char dcmd;
3678 int size;
3679
3680 dcmd = (insn[0] >> 24) & 0xff;
3681 sprintf(buf, "%s%08lx : 0x%08lx 0x%08lx", (prefix ? prefix : ""),
3682 (unsigned long) insn, insn[0], insn[1]);
3683 tmp = buf + strlen(buf);
3684 if ((dcmd & DCMD_TYPE_MASK) == DCMD_TYPE_MMI) {
3685 sprintf (tmp, " 0x%08lx\n", insn[2]);
3686 size = 3;
3687 } else {
3688 sprintf (tmp, "\n");
3689 size = 2;
3690 }
3691
3692 if (kernel)
3693 printk ("%s", buf);
3694 #ifdef NCR_DEBUG
3695 else {
3696 size_t len = strlen(buf);
3697 debugger_kernel_write(host, buf, len);
3698 }
3699 #endif
3700 return size;
3701 }
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715 int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
3716 struct Scsi_Host *host = cmd->host;
3717 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3718 host->hostdata;
3719 unsigned long flags;
3720 struct NCR53c7x0_cmd *curr, **prev;
3721 save_flags(flags);
3722 cli();
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734 for (curr = (struct NCR53c7x0_cmd *) hostdata->issue_queue,
3735 prev = (struct NCR53c7x0_cmd **) &(hostdata->issue_queue);
3736 curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **)
3737 &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
3738
3739 if (curr) {
3740 *prev = (struct NCR53c7x0_cmd *) curr->next;
3741
3742 if (curr->prev)
3743 curr->prev->next = curr->next;
3744
3745 curr->next = hostdata->free;
3746 hostdata->free = curr;
3747
3748 cmd->result = 0;
3749 cmd->scsi_done(cmd);
3750 restore_flags(flags);
3751 return SCSI_ABORT_SUCCESS;
3752 }
3753
3754
3755
3756
3757
3758
3759 for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list,
3760 prev = (struct NCR53c7x0_cmd **) &(hostdata->running_list);
3761 curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **)
3762 &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
3763
3764 if (curr) {
3765 restore_flags(flags);
3766 printk ("scsi%d : DANGER : command in running list, can not abort.\n",
3767 cmd->host->host_no);
3768 return SCSI_ABORT_SNOOZE;
3769 }
3770
3771
3772
3773
3774
3775
3776
3777 curr = (struct NCR53c7x0_cmd *) cmd->host_scribble;
3778 curr->next = hostdata->free;
3779 hostdata->free = curr;
3780
3781 if (((cmd->result & 0xff00) == 0xff00) ||
3782 ((cmd->result & 0xff) == 0xff)) {
3783 printk ("scsi%d : did this command ever run?\n", host->host_no);
3784 } else {
3785 printk ("scsi%d : probably lost INTFLY, normal completion\n",
3786 host->host_no);
3787 }
3788 cmd->scsi_done(cmd);
3789 restore_flags(flags);
3790 return SCSI_ABORT_SNOOZE;
3791 }
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804 int
3805 NCR53c7xx_reset (Scsi_Cmnd *cmd) {
3806 NCR53c7x0_local_declare();
3807 unsigned long flags;
3808 int found;
3809 struct NCR53c7x0_cmd * c;
3810 Scsi_Cmnd *tmp;
3811 struct Scsi_Host *host = cmd->host;
3812 struct NCR53c7x0_hostdata *hostdata = host ?
3813 (struct NCR53c7x0_hostdata *) host->hostdata : NULL;
3814 NCR53c7x0_local_setup(host);
3815 save_flags(flags);
3816 halt (host);
3817 NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
3818 udelay(25);
3819 NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
3820 for (c = (struct NCR53c7x0_cmd *) hostdata->running_list, found = 0; c;
3821 c = (struct NCR53c7x0_cmd *) c->next) {
3822 tmp = c->cmd;
3823 c->next = hostdata->free;
3824 hostdata->free = c;
3825
3826 if (tmp == cmd)
3827 found = 1;
3828 tmp->result = DID_RESET << 16;
3829 tmp->scsi_done(tmp);
3830 }
3831 if (!found) {
3832 c = (struct NCR53c7x0_cmd *) cmd->host_scribble;
3833 if (c) {
3834 c->next = hostdata->free;
3835 hostdata->free = c;
3836 }
3837 cmd->result = DID_RESET << 16;
3838 cmd->scsi_done(cmd);
3839 }
3840 restore_flags(flags);
3841
3842 printk ("scsi%d : DANGER : NCR53c7xx_reset is NOP\n",
3843 cmd->host->host_no);
3844 return SCSI_RESET_SUCCESS;
3845 }
3846
3847
3848
3849
3850
3851
3852 static void print_dsa (struct Scsi_Host *host, unsigned long *dsa) {
3853 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3854 host->hostdata;
3855 int i, len;
3856 char *ptr;
3857
3858 printk("scsi%d : dsa at 0x%x\n"
3859 " + %ld : dsa_msgout length = %lu, data = 0x%lx\n" ,
3860 host->host_no, (unsigned) dsa, hostdata->dsa_msgout,
3861 dsa[hostdata->dsa_msgout / sizeof(long)],
3862 dsa[hostdata->dsa_msgout / sizeof(long) + 1]);
3863
3864 for (i = dsa[hostdata->dsa_msgout / sizeof(long)],
3865 ptr = (char *) dsa[hostdata->dsa_msgout / sizeof(long) + 1]; i > 0;
3866 ptr += len, i -= len) {
3867 printk(" ");
3868 len = print_msg (ptr);
3869 printk("\n");
3870 }
3871 }
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882 #ifdef MODULE
3883 static int
3884 shutdown (struct Scsi_Host *host) {
3885 NCR53c7x0_local_declare();
3886 unsigned long flags;
3887 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3888 host->hostdata;
3889 NCR53c7x0_local_setup(host);
3890 save_flags (flags);
3891 cli();
3892 halt (host);
3893 hostdata->soft_reset(host);
3894
3895
3896
3897
3898
3899
3900
3901 NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
3902 udelay(25);
3903 NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
3904 restore_flags (flags);
3905 return 0;
3906 }
3907 #endif
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920 static int
3921 halt (struct Scsi_Host *host) {
3922 NCR53c7x0_local_declare();
3923 unsigned long flags;
3924 unsigned char istat, tmp;
3925 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3926 host->hostdata;
3927 NCR53c7x0_local_setup(host);
3928
3929 save_flags(flags);
3930 cli();
3931 NCR53c7x0_write8(hostdata->istat, ISTAT_ABRT);
3932
3933 for (;;) {
3934 istat = NCR53c7x0_read8 (hostdata->istat);
3935 if (istat & ISTAT_SIP) {
3936 if ((hostdata->chip / 100) == 8) {
3937 tmp = NCR53c7x0_read8(SIST0_REG_800);
3938 udelay(1);
3939 tmp = NCR53c7x0_read8(SIST1_REG_800);
3940 } else {
3941 tmp = NCR53c7x0_read8(SSTAT0_REG);
3942 }
3943 } else if (istat & ISTAT_DIP) {
3944 NCR53c7x0_write8(hostdata->istat, 0);
3945 tmp = NCR53c7x0_read8(DSTAT_REG);
3946 if (tmp & DSTAT_ABRT)
3947 break;
3948 else
3949 panic("scsi%d: could not halt NCR chip\n", host->host_no);
3950 }
3951 }
3952 hostdata->state = STATE_HALTED;
3953 restore_flags(flags);
3954 return 0;
3955 }
3956
3957 #ifdef MODULE
3958 int NCR53c7x0_release(struct Scsi_Host *host) {
3959 shutdown (host);
3960
3961 if (host->irq != IRQ_NONE)
3962 {
3963 int irq_count;
3964 struct Scsi_Host *tmp;
3965 for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
3966 if (tmp->hostt == the_template && tmp->irq == host->irq)
3967 ++irq_count;
3968 if (irq_count == 1)
3969 free_irq(host->irq);
3970 }
3971 if (host->dma_channel != DMA_NONE)
3972 free_dma(host->dma_channel);
3973 return 1;
3974 }
3975 Scsi_Host_Template driver_template = NCR53c7xx;
3976 #include "scsi_module.c"
3977 #endif