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 barrier();
1247
1248 failed = 1;
1249 if (hostdata->test_completed == -1)
1250 printk ("scsi%d : driver test 1 timed out%s\n",host->host_no ,
1251 (hostdata->test_dest == 0xdeadbeef) ?
1252 " due to lost interrupt.\n"
1253 " Please verify that the correct IRQ is being used for your board,\n"
1254 " and that the motherboard IRQ jumpering matches the PCI setup on\n"
1255 " PCI systems.\n"
1256 " If you are using a NCR53c810 board in a PCI system, you should\n"
1257 " also verify that the board is jumpered to use PCI INTA, since\n"
1258 " most PCI motherboards lack support for INTB, INTC, and INTD.\n"
1259 : "");
1260 else if (hostdata->test_completed != 1)
1261 printk ("scsi%d : test 1 bad interrupt value (%ld)\n", host->host_no,
1262 hostdata->test_completed);
1263 else
1264 failed = (hostdata->test_dest != 0xdeadbeef);
1265
1266 if (hostdata->test_dest != 0xdeadbeef) {
1267 printk ("scsi%d : driver test 1 read 0x%x instead of 0xdeadbeef indicating a\n"
1268 " probable cache invalidation problem. Please configure caching\n"
1269 " as write-through or disabled\n",
1270 host->host_no, hostdata->test_dest);
1271 }
1272
1273 if (failed) {
1274 printk ("scsi%d : DSP = 0x%lx (script at 0x%lx, start at 0x%lx)\n",
1275 host->host_no, (unsigned long) NCR53c7x0_read32(DSP_REG),
1276 (unsigned long) hostdata->script, start);
1277 printk ("scsi%d : DSPS = 0x%lx\n", host->host_no,
1278 (unsigned long) NCR53c7x0_read32(DSPS_REG));
1279 restore_flags(flags);
1280 return -1;
1281 }
1282 hostdata->test_running = 0;
1283 }
1284
1285 if (hostdata->issue_dsa_head) {
1286 printk ("scsi%d : hostdata->issue_dsa_head corrupt after test 1\n",
1287 host->host_no);
1288 hostdata->issue_dsa_head = NULL;
1289 }
1290
1291 if (hostdata->options & OPTION_DEBUG_TEST2) {
1292 unsigned long dsa[48];
1293 unsigned char identify = IDENTIFY(0, 0);
1294 unsigned char cmd[6];
1295 unsigned char data[36];
1296 unsigned char status = 0xff;
1297 unsigned char msg = 0xff;
1298
1299 cmd[0] = INQUIRY;
1300 cmd[1] = cmd[2] = cmd[3] = cmd[5] = 0;
1301 cmd[4] = sizeof(data);
1302
1303 dsa[2] = 1;
1304 dsa[3] = (unsigned long) &identify;
1305 dsa[4] = 6;
1306 dsa[5] = (unsigned long) &cmd;
1307 dsa[6] = sizeof(data);
1308 dsa[7] = (unsigned long) &data;
1309 dsa[8] = 1;
1310 dsa[9] = (unsigned long) &status;
1311 dsa[10] = 1;
1312 dsa[11] = (unsigned long) &msg;
1313
1314 for (i = 0; i < 3; ++i) {
1315 cli();
1316 if (!hostdata->idle) {
1317 printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
1318 restore_flags(flags);
1319 return -1;
1320 }
1321
1322
1323 dsa[0] = (0x33 << 24) | (i << 16) ;
1324 hostdata->idle = 0;
1325 hostdata->test_running = 2;
1326 hostdata->test_completed = -1;
1327 start = ((unsigned long) hostdata->script) + hostdata->E_test_2;
1328 hostdata->state = STATE_RUNNING;
1329 NCR53c7x0_write32 (DSA_REG, (unsigned long) dsa);
1330 NCR53c7x0_write32 (DSP_REG, start);
1331 sti();
1332
1333 timeout = jiffies + 500;
1334 while ((hostdata->test_completed == -1) && jiffies < timeout)
1335 barrier();
1336 NCR53c7x0_write32 (DSA_REG, 0);
1337
1338 if (hostdata->test_completed == 2) {
1339 data[35] = 0;
1340 printk ("scsi%d : test 2 INQUIRY to target %d, lun 0 : %s\n",
1341 host->host_no, i, data + 8);
1342 printk ("scsi%d : status ", host->host_no);
1343 print_status (status);
1344 printk ("\nscsi%d : message ", host->host_no);
1345 print_msg (&msg);
1346 printk ("\n");
1347 } else if (hostdata->test_completed == 3) {
1348 printk("scsi%d : test 2 no connection with target %d\n",
1349 host->host_no, i);
1350 if (!hostdata->idle) {
1351 printk("scsi%d : not idle\n", host->host_no);
1352 restore_flags(flags);
1353 return -1;
1354 }
1355 } else if (hostdata->test_completed == -1) {
1356 printk ("scsi%d : test 2 timed out\n", host->host_no);
1357 restore_flags(flags);
1358 return -1;
1359 }
1360 hostdata->test_running = 0;
1361 if (hostdata->issue_dsa_head) {
1362 printk ("scsi%d : hostdata->issue_dsa_head corrupt after test 2 id %d\n",
1363 host->host_no, i);
1364 hostdata->issue_dsa_head = NULL;
1365 }
1366 }
1367 }
1368
1369 restore_flags(flags);
1370 return 0;
1371 }
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383 static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
1384 Scsi_Cmnd *c = cmd->cmd;
1385 struct Scsi_Host *host = c->host;
1386 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1387 host->hostdata;
1388 int i;
1389
1390 memcpy (cmd->dsa, hostdata->script + (hostdata->E_dsa_code_template / 4),
1391 hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template);
1392
1393 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1394 dsa_temp_jump_resume, ((unsigned long) cmd->dsa) +
1395 Ent_dsa_jump_resume - Ent_dsa_zero);
1396 patch_abs_rwri_data (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1397 dsa_temp_lun, c->lun);
1398 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1399 dsa_temp_dsa_next, ((unsigned long) cmd->dsa) + A_dsa_next);
1400 patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1401 dsa_temp_sync, hostdata->sync[c->target].select_indirect);
1402 patch_abs_rwri_data (cmd->dsa, Ent_dsa_code_template / sizeof(long),
1403 dsa_temp_target, c->target);
1404 }
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421 static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
1422 Scsi_Cmnd *c = cmd->cmd;
1423 struct Scsi_Host *host = c->host;
1424 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1425 host->hostdata;
1426 unsigned long flags;
1427 char **prev, *search;
1428 int i;
1429
1430 save_flags(flags);
1431 cli();
1432 for (i = 0; i < 2; ++i) {
1433 for (search = (char *) (i ? hostdata->issue_dsa_head :
1434 hostdata->reconnect_dsa_head), prev = (char **) (i ?
1435 &(hostdata->issue_dsa_head) : &(hostdata->reconnect_dsa_head));
1436 search && (search + hostdata->dsa_start) != (char *) cmd->dsa;
1437 prev = (char **) (search + hostdata->dsa_next),
1438 search = *prev);
1439
1440 if (search)
1441 *prev = *(char **) (search + hostdata->dsa_next);
1442 }
1443
1444 if (cmd->prev)
1445 cmd->prev->next = cmd->next;
1446
1447 if (cmd->next)
1448 cmd->next->prev = cmd->prev;
1449
1450 if (hostdata->running_list == cmd)
1451 hostdata->running_list = cmd->next;
1452
1453 cmd->next = hostdata->free;
1454 hostdata->free = cmd;
1455
1456 c->host_scribble = NULL;
1457 c->result = result;
1458 c->scsi_done(c);
1459
1460 restore_flags(flags);
1461 }
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475 static void intr_break (struct Scsi_Host *host, struct
1476 NCR53c7x0_cmd *cmd) {
1477 NCR53c7x0_local_declare();
1478 struct NCR53c7x0_break *bp;
1479 #if 0
1480 Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
1481 #endif
1482 unsigned long *dsp;
1483 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1484 host->hostdata;
1485 unsigned long flags;
1486 NCR53c7x0_local_setup(host);
1487
1488
1489
1490
1491
1492
1493 save_flags(flags);
1494 cli();
1495 dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
1496 for (bp = hostdata->breakpoints; bp && bp->address != dsp;
1497 bp = bp->next);
1498 if (!bp)
1499 panic("scsi%d : break point interrupt from %p with no breakpoint!",
1500 host->host_no, dsp);
1501
1502
1503
1504
1505
1506
1507
1508 NCR53c7x0_write8 (hostdata->dmode,
1509 NCR53c7x0_read8(hostdata->dmode)|DMODE_MAN);
1510
1511
1512
1513
1514
1515
1516 restore_flags(flags);
1517 }
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530 static int asynchronous (struct Scsi_Host *host, int target) {
1531 NCR53c7x0_local_declare();
1532 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1533 host->hostdata;
1534 NCR53c7x0_local_setup(host);
1535
1536 if ((hostdata->chip / 100) == 8) {
1537 hostdata->sync[target].select_indirect = (hostdata->saved_scntl3 << 24)
1538 | (target << 16);
1539
1540 } else if ((hostdata->chip != 700) && (hostdata->chip != 70066)) {
1541 hostdata->sync[target].select_indirect = (1 << (target & 7)) << 16;
1542 }
1543
1544
1545
1546
1547
1548
1549 if (hostdata->state == STATE_HALTED) {
1550 if ((hostdata->chip / 100) == 8) {
1551 NCR53c7x0_write8 (SCNTL3_REG_800, hostdata->saved_scntl3);
1552 }
1553
1554 NCR53c7x0_write8 (SXFER_REG, 0);
1555 }
1556 return 0;
1557 }
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567 static const struct {
1568 int div;
1569 unsigned char scf;
1570 unsigned char tp;
1571 } syncs[] = {
1572
1573 { 40, 1, 0}, { 50, 1, 1}, { 60, 1, 2},
1574 { 70, 1, 3}, { 75, 2, 1}, { 80, 1, 4},
1575 { 90, 1, 5}, { 100, 1, 6}, { 105, 2, 3},
1576 { 110, 1, 7}, { 120, 2, 4}, { 135, 2, 5},
1577 { 140, 3, 3}, { 150, 2, 6}, { 160, 3, 4},
1578 { 165, 2, 7}, { 180, 3, 5}, { 200, 3, 6},
1579 { 210, 4, 3}, { 220, 3, 7}, { 240, 4, 4},
1580 { 270, 4, 5}, { 300, 4, 6}, { 330, 4, 7}
1581 };
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598 static void synchronous (struct Scsi_Host *host, int target, char *msg) {
1599 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1600 host->hostdata;
1601 int desire, divisor, i, limit;
1602 unsigned long *script;
1603 unsigned char scntl3, sxfer;
1604
1605
1606 desire = 1000000000L / (msg[3] * 4);
1607 divisor = desire / (hostdata->scsi_clock / 10);
1608
1609 if (msg[4] > 8)
1610 msg[4] = 8;
1611
1612 printk("scsi%d : optimal synchronous divisor of %d.%01d\n", host->host_no,
1613 divisor / 10, divisor % 10);
1614
1615 limit = (sizeof(syncs) / sizeof(syncs[0])) - 1;
1616 for (i = 0; (i < limit) && (divisor < syncs[i + 1].div); ++i);
1617
1618 printk("scsi%d : selected synchronous divisor of %d.%01d\n", host->host_no,
1619 syncs[i].div / 10, syncs[i].div % 10);
1620
1621 msg[3] = (1000000000 / divisor / 10 / 4);
1622
1623 scntl3 = (hostdata->chip / 100 == 8) ? ((hostdata->saved_scntl3 &
1624 ~SCNTL3_800_SCF_MASK) | (syncs[i].scf << SCNTL3_800_SCF_SHIFT)) : 0;
1625 sxfer = (msg[4] << SXFER_MO_SHIFT) | ((syncs[i].tp) << SXFER_TP_SHIFT);
1626
1627 if ((hostdata->chip != 700) && (hostdata->chip != 70066)) {
1628 hostdata->sync[target].select_indirect = (scntl3 << 24) | (target << 16) |
1629 (sxfer << 8);
1630
1631 script = (long *) hostdata->sync[target].script;
1632
1633
1634 if ((hostdata->chip / 100) == 8) {
1635 script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
1636 DCMD_RWRI_OP_MOVE) << 24) |
1637 (SCNTL3_REG_800 << 16) | (scntl3 << 8);
1638 script[1] = 0;
1639 script += 2;
1640 }
1641
1642 script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
1643 DCMD_RWRI_OP_MOVE) << 24) |
1644 (SXFER_REG << 16) | (sxfer << 8);
1645 script[1] = 0;
1646 script += 2;
1647
1648 script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_RETURN) << 24) | DBC_TCI_TRUE;
1649 script[1] = 0;
1650 script += 2;
1651 }
1652 }
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667 static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
1668 NCR53c7x0_cmd *cmd) {
1669 NCR53c7x0_local_declare();
1670 Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
1671 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1672 host->hostdata;
1673 unsigned long dsps,*dsp;
1674 NCR53c7x0_local_setup(host);
1675 dsps = NCR53c7x0_read32(DSPS_REG);
1676 dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
1677
1678 if (hostdata->options & OPTION_DEBUG_INTR)
1679 printk ("scsi%d : DSPS = 0x%lx\n", host->host_no, dsps);
1680
1681 switch (dsps) {
1682 case A_int_msg_1:
1683 printk ("scsi%d : message", host->host_no);
1684 if (cmd)
1685 printk (" from target %d lun %d", c->target, c->lun);
1686 print_msg ((unsigned char *) hostdata->msg_buf);
1687 printk("\n");
1688 switch (hostdata->msg_buf[0]) {
1689
1690
1691
1692
1693 case MESSAGE_REJECT:
1694 hostdata->dsp = hostdata->script + hostdata->E_accept_message /
1695 sizeof(long);
1696 hostdata->dsp_changed = 1;
1697 break;
1698 case INITIATE_RECOVERY:
1699 printk ("scsi%d : extended contingent allegiance not supported yet, rejecting\n",
1700 host->host_no);
1701 hostdata->dsp = hostdata->script + hostdata->E_reject_message /
1702 sizeof(long);
1703 hostdata->dsp_changed = 1;
1704 }
1705 return SPECIFIC_INT_NOTHING;
1706 case A_int_msg_sdtr:
1707 if (cmd) {
1708 printk ("scsi%d : target %d %s synchronous transfer period %dns, offset%d\n",
1709 host->host_no, c->target, (cmd->flags & CMD_FLAG_SDTR) ? "accepting" :
1710 "requesting", hostdata->msg_buf[3] * 4, hostdata->msg_buf[4]);
1711
1712
1713
1714
1715
1716
1717
1718
1719 if (cmd->flags & CMD_FLAG_SDTR) {
1720 cmd->flags &= ~CMD_FLAG_SDTR;
1721 synchronous (host, c->target, (unsigned char *)
1722 hostdata->msg_buf);
1723 hostdata->dsp = hostdata->script + hostdata->E_accept_message /
1724 sizeof(long);
1725 hostdata->dsp_changed = 1;
1726 return SPECIFIC_INT_NOTHING;
1727 } else {
1728 if (hostdata->options & OPTION_SYNCHRONOUS) {
1729 cmd->flags |= CMD_FLAG_DID_SDTR;
1730 synchronous (host, c->target, (unsigned char *)
1731 hostdata->msg_buf);
1732 } else {
1733 hostdata->msg_buf[4] = 0;
1734 }
1735
1736 patch_dsa_32 (cmd->dsa, dsa_msgout_other, 0, 5);
1737 patch_dsa_32 (cmd->dsa, dsa_msgout_other, 1,
1738 hostdata->msg_buf);
1739 hostdata->dsp = hostdata->script +
1740 hostdata->E_respond_message / sizeof(long);
1741 hostdata->dsp_changed = 1;
1742 }
1743
1744 if (hostdata->msg_buf[4]) {
1745 int Hz = 1000000000 / (hostdata->msg_buf[3] * 4);
1746 printk ("scsi%d : setting target %d to %d.%02dMhz %s SCSI%s\n"
1747 " period = %dns, max offset = %d\n",
1748 host->host_no, c->target, Hz / 1000000, Hz % 1000000,
1749 ((hostdata->msg_buf[3] < 200) ? "FAST " :
1750 "synchronous") ,
1751 ((hostdata->msg_buf[3] < 200) ? "-II" : ""),
1752 (int) hostdata->msg_buf[3] * 4, (int)
1753 hostdata->msg_buf[4]);
1754 } else {
1755 printk ("scsi%d : setting target %d to asynchronous SCSI\n",
1756 host->host_no, c->target);
1757 }
1758 return SPECIFIC_INT_NOTHING;
1759 }
1760
1761 case A_int_msg_wdtr:
1762 hostdata->dsp = hostdata->script + hostdata->E_reject_message /
1763 sizeof(long);
1764 hostdata->dsp_changed = 1;
1765 return SPECIFIC_INT_NOTHING;
1766 case A_int_err_unexpected_phase:
1767 if (hostdata->options & OPTION_DEBUG_INTR)
1768 printk ("scsi%d : unexpected phase\n", host->host_no);
1769 return SPECIFIC_INT_ABORT;
1770 case A_int_err_selected:
1771 printk ("scsi%d : selected by target %d\n", host->host_no,
1772 (int) NCR53c7x0_read8(SSID_REG_800) &7);
1773 hostdata->dsp = hostdata->script + hostdata->E_target_abort /
1774 sizeof(long);
1775 hostdata->dsp_changed = 1;
1776 return SPECIFIC_INT_NOTHING;
1777 case A_int_err_unexpected_reselect:
1778 printk ("scsi%d : unexpected reselect by target %d\n", host->host_no,
1779 (int) NCR53c7x0_read8(SSID_REG_800));
1780 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
1781 sizeof(long);
1782 hostdata->dsp_changed = 1;
1783 return SPECIFIC_INT_NOTHING;
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793 case A_int_err_check_condition:
1794 #if 0
1795 if (hostdata->options & OPTION_DEBUG_INTR)
1796 #endif
1797 printk ("scsi%d : CHECK CONDITION\n", host->host_no);
1798 if (!c) {
1799 printk("scsi%d : CHECK CONDITION with no SCSI command\n",
1800 host->host_no);
1801 return SPECIFIC_INT_PANIC;
1802 }
1803
1804
1805
1806
1807
1808
1809 asynchronous (host, c->target);
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821 patch_dsa_32 (cmd->dsa, dsa_msgout, 0, 1);
1822
1823
1824
1825
1826
1827
1828 patch_dsa_32 (cmd->dsa, dsa_cmdout, 0, 6);
1829
1830 c->cmnd[0] = REQUEST_SENSE;
1831 c->cmnd[1] &= 0xe0;
1832 c->cmnd[2] = 0;
1833 c->cmnd[3] = 0;
1834 c->cmnd[4] = sizeof(c->sense_buffer);
1835 c->cmnd[5] = 0;
1836
1837
1838
1839
1840
1841
1842
1843 patch_dsa_32 (cmd->dsa, dsa_dataout, 0, hostdata->E_other_transfer);
1844 patch_dsa_32 (cmd->dsa, dsa_datain, 0, cmd->data_transfer_start);
1845 cmd->data_transfer_start[0] = (((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I |
1846 DCMD_BMI_IO)) << 24) | sizeof(c->sense_buffer);
1847 cmd->data_transfer_start[1] = (unsigned long) c->sense_buffer;
1848
1849 cmd->data_transfer_start[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP)
1850 << 24) | DBC_TCI_TRUE;
1851 cmd->data_transfer_start[3] = hostdata->E_other_transfer;
1852
1853
1854
1855
1856
1857
1858
1859
1860 cmd->cmd->result = 0xffff;
1861
1862
1863
1864
1865 hostdata->dsp = hostdata->script + hostdata->E_select /
1866 sizeof(long);
1867 hostdata->dsp_changed = 1;
1868 return SPECIFIC_INT_NOTHING;
1869 case A_int_debug_break:
1870 return SPECIFIC_INT_BREAK;
1871 case A_int_norm_aborted:
1872 hostdata->dsp = hostdata->script + hostdata->E_schedule /
1873 sizeof(long);
1874 hostdata->dsp_changed = 1;
1875 if (cmd)
1876 abnormal_finished (cmd, DID_ERROR << 16);
1877 return SPECIFIC_INT_NOTHING;
1878 case A_int_test_1:
1879 case A_int_test_2:
1880 hostdata->idle = 1;
1881 hostdata->test_completed = (dsps - A_int_test_1) / 0x00010000 + 1;
1882 if (hostdata->options & OPTION_DEBUG_INTR)
1883 printk("scsi%d : test%ld complete\n", host->host_no,
1884 hostdata->test_completed);
1885 return SPECIFIC_INT_NOTHING;
1886 #ifdef A_int_debug_scheduled
1887 case A_int_debug_scheduled:
1888 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1889 printk("scsi%d : new I/O 0x%lx scheduled\n", host->host_no,
1890 NCR53c7x0_read32(DSA_REG));
1891 }
1892 return SPECIFIC_INT_RESTART;
1893 #endif
1894 #ifdef A_int_debug_idle
1895 case A_int_debug_idle:
1896 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1897 printk("scsi%d : idle\n", host->host_no);
1898 }
1899 return SPECIFIC_INT_RESTART;
1900 #endif
1901 #ifdef A_int_debug_cmd
1902 case A_int_debug_cmd:
1903 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1904 printk("scsi%d : command sent\n");
1905 }
1906 return SPECIFIC_INT_RESTART;
1907 #endif
1908 #ifdef A_int_debug_dsa_loaded
1909 case A_int_debug_dsa_loaded:
1910 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1911 printk("scsi%d : DSA loaded with 0x%lx\n", host->host_no,
1912 NCR53c7x0_read32(DSA_REG));
1913 }
1914 return SPECIFIC_INT_RESTART;
1915 #endif
1916 #ifdef A_int_debug_reselected
1917 case A_int_debug_reselected:
1918 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1919 printk("scsi%d : reselected by target %d lun %d\n",
1920 host->host_no, (int) NCR53c7x0_read8(SSID_REG_800),
1921 (int) hostdata->reselected_identify & 7);
1922 }
1923 return SPECIFIC_INT_RESTART;
1924 #endif
1925 #ifdef A_int_debug_head
1926 case A_int_debug_head:
1927 if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
1928 printk("scsi%d : issue_dsa_head now 0x%lx\n",
1929 host->host_no, (unsigned long) hostdata->issue_dsa_head);
1930 }
1931 return SPECIFIC_INT_RESTART;
1932 #endif
1933 default:
1934 if ((dsps & 0xff000000) == 0x03000000) {
1935 printk ("scsi%d : misc debug interrupt 0x%lx\n",
1936 host->host_no, dsps);
1937 return SPECIFIC_INT_RESTART;
1938 }
1939
1940 printk ("scsi%d : unknown user interrupt 0x%x\n",
1941 host->host_no, (unsigned) dsps);
1942 return SPECIFIC_INT_PANIC;
1943 }
1944 }
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960 #include "53c8xx_u.h"
1961
1962
1963
1964
1965 #ifdef NCR_DEBUG
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980 static const char debugger_help =
1981 "bc <addr> - clear breakpoint\n"
1982 "bl - list breakpoints\n"
1983 "bs <addr> - set breakpoint\n"
1984 "g - start\n"
1985 "h - halt\n"
1986 "? - this message\n"
1987 "i - info\n"
1988 "mp <addr> <size> - print memory\n"
1989 "ms <addr> <size> <value> - store memory\n"
1990 "rp <num> <size> - print register\n"
1991 "rs <num> <size> <value> - store register\n"
1992 "s - single step\n"
1993 "tb - begin trace \n"
1994 "te - end trace\n";
1995
1996
1997
1998
1999
2000
2001 static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token,
2002 unsigned long args[]) {
2003 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2004 instance->hostdata;
2005 struct NCR53c7x0_break *bp, **prev;
2006 unsigned long flags;
2007 save_flags(flags);
2008 cli();
2009 for (bp = (struct NCR53c7x0_break *) instance->breakpoints,
2010 prev = (struct NCR53c7x0_break **) &instance->breakpoints;
2011 bp; prev = (struct NCR53c7x0_break **) &(bp->next),
2012 bp = (struct NCR53c7x0_break *) bp->next);
2013
2014 if (!bp) {
2015 restore_flags(flags);
2016 return -EIO;
2017 }
2018
2019
2020
2021
2022
2023
2024 memcpy ((void *) bp->addr, (void *) bp->old, sizeof(bp->old));
2025 if (prev)
2026 *prev = bp->next;
2027
2028 restore_flags(flags);
2029 return 0;
2030 }
2031
2032
2033 static int debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token,
2034 unsigned long args[]) {
2035 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2036 host->hostdata;
2037 struct NCR53c7x0_break *bp;
2038 char buf[80];
2039 size_t len;
2040 unsigned long flags;
2041
2042
2043
2044
2045
2046
2047 sprintf (buf, "scsi%d : bp : warning : processor not halted\b",
2048 host->host_no);
2049 debugger_kernel_write (host, buf, strlen(buf));
2050
2051 save_flags(flags);
2052 cli();
2053 for (bp = (struct NCR53c7x0_break *) host->breakpoints;
2054 bp; bp = (struct NCR53c7x0_break *) bp->next); {
2055 sprintf (buf, "scsi%d : bp : success : at %08x, replaces %08x %08x",
2056 bp->addr, bp->old[0], bp->old[1]);
2057 len = strlen(buf);
2058 if ((bp->old[0] & (DCMD_TYPE_MASK << 24)) ==
2059 (DCMD_TYPE_MMI << 24)) {
2060 sprintf(buf + len, "%08x\n", * (long *) bp->addr);
2061 } else {
2062 sprintf(buf + len, "\n");
2063 }
2064 len = strlen(buf);
2065 debugger_kernel_write (host, buf, len);
2066 }
2067 restore_flags(flags);
2068 return 0;
2069 }
2070
2071 static int debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token,
2072 unsigned long args[]) {
2073 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2074 host->hostdata;
2075 struct NCR53c7x0_break *bp;
2076 char buf[80];
2077 size_t len;
2078 unsigned long flags;
2079 save_flags(flags);
2080 cli();
2081
2082 if (hostdata->state != STATE_HALTED) {
2083 sprintf (buf, "scsi%d : bs : failure : NCR not halted\n", host->host_no);
2084 debugger_kernel_write (host, buf, strlen(buf));
2085 restore_flags(flags);
2086 return -1;
2087 }
2088
2089 if (!(bp = kmalloc (sizeof (struct NCR53c7x0_break)))) {
2090 printk ("scsi%d : kmalloc(%d) of breakpoint structure failed, try again\n",
2091 host->host_no, sizeof(struct NCR53c7x0_break));
2092 restore_flags(flags);
2093 return -1;
2094 }
2095
2096 bp->address = (unsigned long *) args[0];
2097 memcpy ((void *) bp->old_instruction, (void *) bp->address, 8);
2098 bp->old_size = (((bp->old_instruction[0] >> 24) & DCMD_TYPE_MASK) ==
2099 DCMD_TYPE_MMI ? 3 : 2;
2100 bp->next = hostdata->breakpoints;
2101 hostdata->breakpoints = bp->next;
2102 memcpy ((void *) bp->address, (void *) hostdata->E_debug_break, 8);
2103
2104 restore_flags(flags);
2105 return 0;
2106 }
2107
2108 #define TOKEN(name,nargs) {#name, nargs, debugger_fn_##name}
2109 static const struct debugger_token {
2110 char *name;
2111 int numargs;
2112 int (*fn)(struct debugger_token *token, unsigned long args[]);
2113 } debugger_tokens[] = {
2114 TOKEN(bc,1), TOKEN(bl,0), TOKEN(bs,1), TOKEN(g,0), TOKEN(halt,0),
2115 {DT_help, "?", 0} , TOKEN(h,0), TOKEN(i,0), TOKEN(mp,2),
2116 TOKEN(ms,3), TOKEN(rp,2), TOKEN(rs,2), TOKEN(s,0), TOKEN(tb,0), TOKEN(te,0)
2117 };
2118
2119 #define NDT sizeof(debugger_tokens / sizeof(struct debugger_token))
2120
2121 static struct Scsi_Host * inode_to_host (struct inode *inode) {$
2122 int dev;
2123 struct Scsi_Host *tmp;
2124 for (dev = MINOR(inode->rdev), host = first_host;
2125 (host->hostt == the_template); --dev, host = host->next)
2126 if (!dev) return host;
2127 return NULL;
2128 }
2129
2130
2131 static debugger_user_write (struct inode *inode,struct file *filp,
2132 char *buf,int count) {
2133 struct Scsi_Host *host;
2134 struct NCR53c7x0_hostadata *hostdata;
2135 char input_buf[80],
2136 *ptr;
2137 unsigned long args[3];
2138 int i, j, error, len;
2139
2140 if (!(host = inode_to_host(inode)))
2141 return -ENXIO;
2142
2143 hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
2144
2145 if (error = verify_area(VERIFY_READ,buf,count))
2146 return error;
2147
2148 if (count > 80)
2149 return -EIO;
2150
2151 memcpy_from_fs(input_buf, buf, count);
2152
2153 if (input_buf[count - 1] != '\n')
2154 return -EIO;
2155
2156 input_buf[count - 1]=0;
2157
2158 for (i = 0; i < NDT; ++i) {
2159 len = strlen (debugger_tokens[i].name);
2160 if (!strncmp(input_buf, debugger_tokens[i].name, len))
2161 break;
2162 };
2163
2164 if (i == NDT)
2165 return -EIO;
2166
2167 for (ptr = input_buf + len, j = 0; j < debugger_tokens[i].nargs && *ptr;) {
2168 if (*ptr == ' ' || *ptr == '\t') {
2169 ++ptr;
2170 } else if (isdigit(*ptr)) {
2171 args[j++] = simple_strtoul (ptr, &ptr, 0);
2172 } else {
2173 return -EIO;
2174 }
2175 }
2176
2177 if (j != debugger_tokens[i].nargs)
2178 return -EIO;
2179
2180 return count;
2181 }
2182
2183 static debugger_user_read (struct inode *inode,struct file *filp,
2184 char *buf,int count) {
2185 struct Scsi_Host *instance;
2186
2187 }
2188
2189 static debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t
2190 buflen) {
2191 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2192 host->hostdata;
2193 int copy, left;
2194 unsigned long flags;
2195 save_flags(flags);
2196 cli();
2197 while (buflen) {
2198 left = (hostdata->debug_buf + hostdata->debug_size - 1) -
2199 hostdata->debug_write;
2200 copy = (buflen <= left) ? buflen : left;
2201 memcpy (hostdata->debug_write, buf, copy);
2202 buf += copy;
2203 buflen -= copy;
2204 hostdata->debug_count += copy;
2205 if ((hostdata->debug_write += copy) ==
2206 (hostdata->debug_buf + hostdata->debug_size))
2207 hosdata->debug_write = hostdata->debug_buf;
2208 }
2209 restore_flags(flags);
2210 }
2211
2212 #endif
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226 static void
2227 NCR53c8x0_soft_reset (struct Scsi_Host *host) {
2228 NCR53c7x0_local_declare();
2229 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2230 host->hostdata;
2231 NCR53c7x0_local_setup(host);
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244 NCR53c7x0_write8(ISTAT_REG_800, ISTAT_10_SRST);
2245 NCR53c7x0_write8(ISTAT_REG_800, 0);
2246 NCR53c7x0_write8(hostdata->dmode, hostdata->saved_dmode & ~DMODE_MAN);
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257 #ifdef notyet
2258 NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE|SCID_800_SRE);
2259 #else
2260 NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE);
2261 #endif
2262 NCR53c7x0_write8(RESPID_REG_800, hostdata->this_id_mask);
2263
2264
2265
2266
2267
2268
2269 NCR53c7x0_write8(STIME0_REG_800,
2270 ((14 << STIME0_800_SEL_SHIFT) & STIME0_800_SEL_MASK)
2271
2272 #if 0
2273 | ((15 << STIME0_800_HTH_SHIFT) & STIME0_800_HTH_MASK)
2274 #endif
2275 );
2276
2277
2278
2279
2280
2281
2282
2283
2284 NCR53c7x0_write8(DIEN_REG, DIEN_800_MDPE | DIEN_800_BF |
2285 DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_800_IID);
2286
2287
2288 NCR53c7x0_write8(SIEN0_REG_800, ((hostdata->options & OPTION_PARITY) ?
2289 SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
2290 NCR53c7x0_write8(SIEN1_REG_800, SIEN1_800_STO | SIEN1_800_HTH);
2291
2292
2293
2294
2295
2296
2297 NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl);
2298 NCR53c7x0_write8(CTEST4_REG_800, hostdata->saved_ctest4);
2299
2300
2301 NCR53c7x0_write8(STEST3_REG_800, STEST3_800_TE);
2302
2303
2304 }
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323 static struct NCR53c7x0_cmd *
2324 create_cmd (Scsi_Cmnd *cmd) {
2325 NCR53c7x0_local_declare();
2326 struct Scsi_Host *host = cmd->host;
2327 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2328 host->hostdata;
2329 struct NCR53c7x0_cmd *tmp = NULL;
2330 int datain,
2331 dataout;
2332 int data_transfer_instructions,
2333 i;
2334 unsigned long *cmd_datain,
2335 *cmd_dataout;
2336 #ifdef notyet
2337 void *real;
2338 int size;
2339 int alignment;
2340 #endif
2341 unsigned long flags;
2342 NCR53c7x0_local_setup(cmd->host);
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353 #ifdef notyet
2354
2355 if (hostdata->num_commands < host->can_queue &&
2356 !in_scan_scsis &&
2357 !(hostdata->cmd_allocated[cmd->target] & (1 << cmd->lun))) {
2358 for (i = host->hostt->cmd_per_lun - 1; i >= 0 --i) {
2359 #ifdef SCSI_MALLOC
2360
2361
2362 size = (hostdata->max_cmd_size + 511) / 512 * 512;
2363 tmp = (struct NCR53c7x0_cmd *) scsi_malloc (size);
2364 if (!tmp)
2365 break;
2366 tmp->real = (void *) tmp;
2367 #else
2368
2369
2370 size = hostdata->max_cmd_size + 4;
2371 real = kmalloc (size, GFP_ATOMIC);
2372 alignment = 4 - (((unsigned) real) & 3);
2373 tmp = (struct NCR53c7x0_cmd *) (((char *) real) + alignment);
2374 if (!tmp)
2375 break;
2376 tmp->real = real;
2377 #endif
2378 tmp->size = size;
2379
2380 if (i > 0) {
2381 tmp->next = hostdata->free;
2382 hostdata->free = tmp;
2383 }
2384 }
2385 }
2386 #endif
2387 if (!tmp) {
2388 save_flags(flags);
2389 cli();
2390 tmp = (struct NCR53c7x0_cmd *) hostdata->free;
2391 if (tmp) {
2392 hostdata->free = tmp->next;
2393 restore_flags(flags);
2394 } else {
2395 restore_flags(flags);
2396 return NULL;
2397 }
2398 }
2399
2400
2401
2402
2403
2404
2405
2406 switch (cmd->cmnd[0]) {
2407
2408 case INQUIRY:
2409 case MODE_SENSE:
2410 case READ_6:
2411 case READ_10:
2412 case READ_CAPACITY:
2413 case REQUEST_SENSE:
2414 datain = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
2415 dataout = 0;
2416 break;
2417
2418 case MODE_SELECT:
2419 case WRITE_6:
2420 case WRITE_10:
2421 #if 0
2422 printk("scsi%d : command is ", host->host_no);
2423 print_command(cmd->cmnd);
2424 #endif
2425 #if 0
2426 printk ("scsi%d : %d scatter/gather segments\n", host->host_no,
2427 cmd->use_sg);
2428 #endif
2429 datain = 0;
2430 dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
2431 #if 0
2432 hostdata->options |= OPTION_DEBUG_INTR;
2433 #endif
2434 break;
2435
2436
2437
2438
2439 case START_STOP:
2440 case TEST_UNIT_READY:
2441 datain = dataout = 0;
2442 break;
2443
2444
2445
2446
2447 default:
2448 datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
2449 }
2450
2451
2452
2453
2454
2455
2456
2457 data_transfer_instructions = datain + dataout;
2458
2459
2460
2461
2462
2463
2464
2465 if (data_transfer_instructions < 2)
2466 data_transfer_instructions = 2;
2467
2468
2469
2470
2471
2472
2473 tmp->cmd = cmd;
2474 tmp->next = NULL;
2475 tmp->prev = NULL;
2476
2477
2478
2479
2480
2481 tmp->data_transfer_start = tmp->dsa + (hostdata->dsa_end -
2482 hostdata->dsa_start) / sizeof(long);
2483 tmp->data_transfer_end = tmp->data_transfer_start +
2484 2 * data_transfer_instructions;
2485
2486 cmd_datain = datain ? tmp->data_transfer_start : NULL;
2487 cmd_dataout = dataout ? (datain ? cmd_datain + 2 * datain : tmp->
2488 data_transfer_start) : NULL;
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498 if (hostdata->dsa_fixup)
2499 hostdata->dsa_fixup(tmp);
2500
2501 patch_dsa_32(tmp->dsa, dsa_next, 0, NULL);
2502 patch_dsa_32(tmp->dsa, dsa_cmnd, 0, cmd);
2503 patch_dsa_32(tmp->dsa, dsa_select, 0, hostdata->sync[cmd->target].
2504 select_indirect);
2505
2506
2507
2508
2509 patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
2510 #if 0
2511 tmp->select[0] = IDENTIFY (1, cmd->lun);
2512 #else
2513 tmp->select[0] = IDENTIFY (0, cmd->lun);
2514 #endif
2515 patch_dsa_32(tmp->dsa, dsa_msgout, 1, tmp->select);
2516 patch_dsa_32(tmp->dsa, dsa_cmdout, 0, cmd->cmd_len);
2517 patch_dsa_32(tmp->dsa, dsa_cmdout, 1, cmd->cmnd);
2518 patch_dsa_32(tmp->dsa, dsa_dataout, 0, cmd_dataout ?
2519 cmd_dataout : hostdata->script + hostdata->E_other_transfer /
2520 sizeof (long));
2521 patch_dsa_32(tmp->dsa, dsa_datain, 0, cmd_datain ?
2522 cmd_datain : hostdata->script + hostdata->E_other_transfer /
2523 sizeof (long));
2524
2525
2526
2527
2528 patch_dsa_32(tmp->dsa, dsa_msgin, 0, 1);
2529 patch_dsa_32(tmp->dsa, dsa_msgin, 1, (((unsigned long) &cmd->result) + 1));
2530 patch_dsa_32(tmp->dsa, dsa_status, 0, 1);
2531 patch_dsa_32(tmp->dsa, dsa_status, 1, &cmd->result);
2532 patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, 1);
2533 patch_dsa_32(tmp->dsa, dsa_msgout_other, 1,
2534 &(hostdata->NCR53c7xx_msg_nop));
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549 #if 0
2550 if (datain) {
2551 cmd_datain[0] = 0x98080000;
2552 cmd_datain[1] = 0x03ffd00d;
2553 cmd_datain += 2;
2554 }
2555 #endif
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572 for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4,
2573 cmd_dataout += 4, ++i) {
2574 unsigned long buf = (unsigned long) (cmd->use_sg ?
2575 ((struct scatterlist *)cmd->buffer)[i].address :
2576 cmd->request_buffer);
2577 unsigned long count = (unsigned long) (cmd->use_sg ?
2578 ((struct scatterlist *)cmd->buffer)[i].length :
2579 cmd->request_bufflen);
2580
2581 if (datain) {
2582 cmd_datain[0] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | DCMD_BMI_IO)
2583 << 24) | count;
2584 cmd_datain[1] = buf;
2585 cmd_datain[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
2586 DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) |
2587 DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE;
2588 cmd_datain[3] = (unsigned long) hostdata->script +
2589 hostdata->E_msg_in;
2590 #if 0
2591 print_insn (host, cmd_datain, "dynamic ", 1);
2592 print_insn (host, cmd_datain + 2, "dynamic ", 1);
2593 #endif
2594 }
2595 if (dataout) {
2596 cmd_dataout[0] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I) << 24)
2597 | count;
2598 cmd_dataout[1] = buf;
2599 cmd_dataout[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
2600 DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) |
2601 DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE;
2602 cmd_dataout[3] = (unsigned long) hostdata->script +
2603 hostdata->E_msg_in;
2604 #if 0
2605 print_insn (host, cmd_dataout, "dynamic ", 1);
2606 print_insn (host, cmd_dataout + 2, "dynamic ", 1);
2607 #endif
2608 }
2609 }
2610
2611
2612
2613
2614
2615
2616
2617 if (datain) {
2618 cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
2619 DBC_TCI_TRUE;
2620 cmd_datain[1] = (unsigned long) hostdata->script +
2621 hostdata->E_other_transfer;
2622 #if 0
2623 print_insn (host, cmd_datain, "dynamic jump ", 1);
2624 #endif
2625 cmd_datain += 2;
2626 }
2627 #if 0
2628 if (datain) {
2629 cmd_datain[0] = 0x98080000;
2630 cmd_datain[1] = 0x03ffdeed;
2631 cmd_datain += 2;
2632 }
2633 #endif
2634
2635
2636 if (dataout) {
2637 cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
2638 DBC_TCI_TRUE;
2639 cmd_dataout[1] = (unsigned long) hostdata->script +
2640 hostdata->E_other_transfer;
2641 #if 0
2642 print_insn (host, cmd_dataout, "dynamic jump ", 1);
2643 #endif
2644 cmd_dataout += 2;
2645 }
2646
2647
2648 return tmp;
2649 }
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669 int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
2670 NCR53c7x0_local_declare();
2671 struct NCR53c7x0_cmd *tmp;
2672 struct Scsi_Host *host = cmd->host;
2673 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2674 host->hostdata;
2675 unsigned long flags;
2676 unsigned char target_was_busy;
2677 NCR53c7x0_local_setup(host);
2678
2679 if (((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY)) ||
2680 ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
2681 !(hostdata->debug_lun_limit[cmd->target] & (1 << cmd->lun)))) ||
2682 cmd->target > 7) {
2683 printk("scsi%d : disabled target %d lun %d\n", host->host_no,
2684 cmd->target, cmd->lun);
2685 cmd->result = (DID_BAD_TARGET << 16);
2686 done(cmd);
2687 return 0;
2688 }
2689
2690 if (hostdata->options & OPTION_DEBUG_NCOMMANDS_LIMIT) {
2691 if (hostdata->debug_count_limit == 0) {
2692 printk("scsi%d : maximum commands exceeded\n", host->host_no);
2693 cmd->result = (DID_BAD_TARGET << 16);
2694 done(cmd);
2695 return 0;
2696 } else if (hostdata->debug_count_limit != -1)
2697 --hostdata->debug_count_limit;
2698 }
2699
2700 if (hostdata->options & OPTION_DEBUG_READ_ONLY) {
2701 switch (cmd->cmnd[0]) {
2702 case WRITE_6:
2703 case WRITE_10:
2704 printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
2705 host->host_no);
2706 cmd->result = (DID_BAD_TARGET << 16);
2707 done(cmd);
2708 return 0;
2709 }
2710 }
2711
2712 cmd->scsi_done = done;
2713 cmd->result = 0xffff;
2714
2715
2716 cmd->host_scribble = (unsigned char *) tmp = create_cmd (cmd);
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
2742
2743 save_flags(flags);
2744 cli();
2745
2746
2747
2748
2749
2750
2751
2752
2753 target_was_busy = hostdata->busy[cmd->target][cmd->lun]
2754 #ifdef LUN_BUSY
2755 ++
2756 #endif
2757 ;
2758
2759 if (!(hostdata->options & OPTION_700) &&
2760 !target_was_busy) {
2761 unsigned char *dsa = ((unsigned char *) tmp->dsa)
2762 - hostdata->dsa_start;
2763
2764 #if 0
2765 printk("scsi%d : new dsa is 0x%x\n", host->host_no, (unsigned) dsa);
2766 #endif
2767
2768 if (hostdata->running_list)
2769 hostdata->running_list->prev = tmp;
2770
2771 tmp->next = hostdata->running_list;
2772
2773 if (!hostdata->running_list)
2774 hostdata->running_list = tmp;
2775
2776
2777 if (hostdata->idle) {
2778 hostdata->idle = 0;
2779 hostdata->state = STATE_RUNNING;
2780 NCR53c7x0_write32 (DSP_REG, ((unsigned long) hostdata->script) +
2781 hostdata->E_schedule);
2782 }
2783
2784
2785 for (;;) {
2786
2787
2788
2789
2790
2791
2792 if (!hostdata->issue_dsa_head) {
2793 #if 0
2794 printk ("scsi%d : no issue queue\n", host->host_no);
2795 #endif
2796 hostdata->issue_dsa_tail = hostdata->issue_dsa_head = dsa;
2797 NCR53c7x0_write8(hostdata->istat,
2798 NCR53c7x0_read8(hostdata->istat) | ISTAT_10_SIGP);
2799 break;
2800
2801
2802
2803
2804
2805
2806
2807 } else {
2808 printk ("scsi%d : existing issue queue\n", host->host_no);
2809
2810 hostdata->issue_dsa_tail = *((unsigned char **)
2811 (hostdata->issue_dsa_tail + hostdata->dsa_next)) = dsa;
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823 if (hostdata->issue_dsa_head)
2824 break;
2825 }
2826 }
2827
2828 } else {
2829 #if 1
2830 printk ("scsi%d : using issue_queue instead of issue_dsa_head!\n",
2831 host->host_no);
2832 #endif
2833 for (tmp = (struct NCR53c7x0_cmd *) hostdata->issue_queue;
2834 tmp->next; tmp = (struct NCR53c7x0_cmd *) tmp->next);
2835 tmp->next = tmp;
2836 }
2837 restore_flags(flags);
2838 return 0;
2839 }
2840
2841
2842 int fix_pointers (unsigned long dsa) {
2843 return 0;
2844 }
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857 static void intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
2858 NCR53c7x0_local_declare();
2859 struct NCR53c7x0_hostdata *hostdata =
2860 (struct NCR53c7x0_hostdata *) host->hostdata;
2861 unsigned char sstat0_sist0, sist1,
2862 fatal;
2863
2864 NCR53c7x0_local_setup(host);
2865
2866 fatal = 0;
2867
2868 if ((hostdata->chip / 100) == 8) {
2869 sstat0_sist0 = NCR53c7x0_read8(SIST0_REG_800);
2870 udelay(1);
2871 sist1 = NCR53c7x0_read8(SIST1_REG_800);
2872 } else {
2873 sstat0_sist0 = NCR53c7x0_read8(SSTAT0_REG);
2874 sist1 = 0;
2875 }
2876
2877 if (hostdata->options & OPTION_DEBUG_INTR)
2878 printk ("scsi%d : SIST0 0x%0x, SIST1 0x%0x\n", host->host_no,
2879 sstat0_sist0, sist1);
2880
2881
2882 if ((((hostdata->chip / 100) == 8) && (sist1 & SIST1_800_STO)) ||
2883 (((hostdata->chip / 100) != 8) && (sstat0_sist0 & SSTAT0_700_STO))) {
2884 fatal = 1;
2885 if (hostdata->options & OPTION_DEBUG_INTR) {
2886 printk ("scsi%d : Selection Timeout\n", host->host_no);
2887 if (cmd) {
2888 printk("scsi%d : target %d, lun %d, command ",
2889 host->host_no, cmd->cmd->target, cmd->cmd->lun);
2890 print_command (cmd->cmd->cmnd);
2891 printk("scsi%d : dsp = 0x%x\n", host->host_no,
2892 (unsigned) NCR53c7x0_read32(DSP_REG));
2893 } else {
2894 printk("scsi%d : no command\n", host->host_no);
2895 }
2896 }
2897
2898
2899
2900
2901
2902
2903 if (1) {
2904 hostdata->idle = 1;
2905 hostdata->expecting_sto = 0;
2906
2907 if (hostdata->test_running) {
2908 hostdata->test_running = 0;
2909 hostdata->test_completed = 3;
2910 } else if (cmd) {
2911 abnormal_finished(cmd, DID_BAD_TARGET << 16);
2912 }
2913 #if 0
2914 hostdata->intrs = 0;
2915 #endif
2916 }
2917 }
2918
2919 if (sstat0_sist0 & SSTAT0_UDC) {
2920 fatal = 1;
2921 if (cmd) {
2922 printk("scsi%d : target %d lun %d unexpected disconnect\n",
2923 host->host_no, cmd->cmd->target, cmd->cmd->lun);
2924 abnormal_finished(cmd, DID_ERROR << 16);
2925 }
2926 hostdata->dsp = hostdata->script + hostdata->E_schedule /
2927 sizeof(long);
2928 hostdata->dsp_changed = 1;
2929
2930 }
2931
2932 if (sstat0_sist0 & SSTAT0_PAR) {
2933 fatal = 1;
2934 if (cmd && cmd->cmd) {
2935 printk("scsi%d : target %d lun %d parity error.\n",
2936 host->host_no, cmd->cmd->target, cmd->cmd->lun);
2937 abnormal_finished (cmd, DID_PARITY << 16);
2938 } else
2939 printk("scsi%d : parity error\n", host->host_no);
2940
2941
2942
2943 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
2944 sizeof(long);
2945 hostdata->dsp_changed = 1;
2946
2947 }
2948
2949 if (sstat0_sist0 & SSTAT0_SGE) {
2950 fatal = 1;
2951 printk("scsi%d : gross error\n", host->host_no);
2952
2953 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
2954 sizeof(long);
2955 hostdata->dsp_changed = 1;
2956
2957 }
2958
2959 if (sstat0_sist0 & SSTAT0_MA) {
2960 fatal = 1;
2961 if (hostdata->options & OPTION_DEBUG_INTR)
2962 printk ("scsi%d : SSTAT0_MA\n", host->host_no);
2963 intr_phase_mismatch (host, cmd);
2964 }
2965
2966 #if 1
2967
2968
2969
2970
2971
2972 if (fatal) {
2973 if (!hostdata->dstat_valid) {
2974 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
2975 hostdata->dstat_valid = 1;
2976 }
2977
2978
2979 if (!(hostdata->dstat & DSTAT_DFE)) {
2980 printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
2981 #if 0
2982 if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
2983 NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
2984 while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
2985 DSTAT_DFE));
2986 } else
2987 #endif
2988 {
2989 NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
2990 while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
2991 }
2992 }
2993
2994 NCR53c7x0_write8 (STEST3_REG_800, STEST3_800_CSF);
2995 while (NCR53c7x0_read8 (STEST3_REG_800) & STEST3_800_CSF);
2996 }
2997 #endif
2998 }
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011 static void NCR53c7x0_intr (int irq, struct pt_regs * regs) {
3012 NCR53c7x0_local_declare();
3013 struct Scsi_Host *host;
3014 unsigned char istat;
3015 struct NCR53c7x0_hostdata *hostdata;
3016 struct NCR53c7x0_cmd *cmd,
3017 **cmd_prev_ptr;
3018 unsigned long *dsa;
3019 int done = 1;
3020
3021 int interrupted = 0;
3022
3023 unsigned long flags;
3024
3025 #ifdef NCR_DEBUG
3026 char buf[80];
3027 size_t buflen;
3028 #endif
3029
3030 #if 0
3031 printk("interrupt %d received\n", irq);
3032 #endif
3033
3034 do {
3035 done = 1;
3036 for (host = first_host; host; host = hostdata->next ?
3037 hostdata->next : NULL) {
3038 NCR53c7x0_local_setup(host);
3039
3040 hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
3041 hostdata->dsp_changed = 0;
3042 interrupted = 0;
3043
3044
3045 do {
3046 hostdata->dstat_valid = 0;
3047 interrupted = 0;
3048
3049
3050
3051
3052 istat = NCR53c7x0_read8(hostdata->istat);
3053
3054
3055
3056
3057
3058
3059
3060
3061 if ((hostdata->options & OPTION_INTFLY) &&
3062 ((hostdata->chip / 100) == 8 && (istat & ISTAT_800_INTF))) {
3063 char search_found = 0;
3064 done = 0;
3065 interrupted = 1;
3066
3067
3068
3069
3070
3071 NCR53c7x0_write8(hostdata->istat, istat|ISTAT_800_INTF);
3072
3073 if (hostdata->options & OPTION_DEBUG_INTR)
3074 printk ("scsi%d : INTFLY\n", host->host_no);
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084 save_flags(flags);
3085 cli();
3086 restart:
3087 for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)
3088 &(hostdata->running_list), cmd =
3089 (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
3090 cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next),
3091 cmd = (struct NCR53c7x0_cmd *) cmd->next) {
3092 Scsi_Cmnd *tmp;
3093
3094 if (!cmd) {
3095 printk("scsi%d : very weird.\n", host->host_no);
3096 break;
3097 }
3098
3099 if (!(tmp = cmd->cmd)) {
3100 printk("scsi%d : weird. NCR53c7x0_cmd has no Scsi_Cmnd\n",
3101 host->host_no);
3102 continue;
3103 }
3104 #if 0
3105 printk ("scsi%d : looking at result of 0x%x\n",
3106 host->host_no, cmd->cmd->result);
3107 #endif
3108
3109 if (((tmp->result & 0xff) == 0xff) ||
3110 ((tmp->result & 0xff00) == 0xff00))
3111 continue;
3112
3113 search_found = 1;
3114
3115
3116
3117 if (cmd->prev)
3118 cmd->prev->next = cmd->next;
3119 if (cmd_prev_ptr)
3120 *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next;
3121
3122 #ifdef LUN_BUSY
3123
3124 if (--hostdata->busy[tmp->target][tmp->lun]) {
3125 }
3126 #endif
3127
3128
3129 cmd->next = hostdata->free;
3130 hostdata->free = cmd;
3131
3132 tmp->host_scribble = NULL;
3133
3134 if (hostdata->options & OPTION_DEBUG_INTR) {
3135 printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 0x%x ",
3136 host->host_no, tmp->pid, tmp->target, tmp->lun, tmp->result);
3137 print_command (tmp->cmnd);
3138 }
3139
3140
3141 #if 0
3142 hostdata->options &= ~OPTION_DEBUG_INTR;
3143 #endif
3144 tmp->scsi_done(tmp);
3145 goto restart;
3146
3147 }
3148 restore_flags(flags);
3149
3150 if (!search_found) {
3151 printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
3152 host->host_no);
3153 }
3154 }
3155
3156 if (istat & (ISTAT_SIP|ISTAT_DIP)) {
3157 done = 0;
3158 interrupted = 1;
3159 hostdata->state = STATE_HALTED;
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170 if (hostdata->options & OPTION_700) {
3171 cmd = (struct NCR53c7x0_cmd *) hostdata->current;
3172 } else {
3173 dsa = (unsigned long *) NCR53c7x0_read32(DSA_REG);
3174 for (cmd = (struct NCR53c7x0_cmd *)
3175 hostdata->running_list; cmd &&
3176 (dsa + (hostdata->dsa_start / sizeof(long))) !=
3177 cmd->dsa;
3178 cmd = (struct NCR53c7x0_cmd *)(cmd->next));
3179 }
3180 if (hostdata->options & OPTION_DEBUG_INTR) {
3181 if (cmd) {
3182 printk("scsi%d : interrupt for pid %lu, id %d, lun %d ",
3183 host->host_no, cmd->cmd->pid, (int) cmd->cmd->target,
3184 (int) cmd->cmd->lun);
3185 print_command (cmd->cmd->cmnd);
3186 } else {
3187 printk("scsi%d : no active command\n", host->host_no);
3188 }
3189 }
3190
3191 if (istat & ISTAT_SIP) {
3192 if (hostdata->options & OPTION_DEBUG_INTR)
3193 printk ("scsi%d : ISTAT_SIP\n", host->host_no);
3194 intr_scsi (host, cmd);
3195 }
3196
3197 if (istat & ISTAT_DIP) {
3198 if (hostdata->options & OPTION_DEBUG_INTR)
3199 printk ("scsi%d : ISTAT_DIP\n", host->host_no);
3200 intr_dma (host, cmd);
3201 }
3202
3203 if (!hostdata->dstat_valid) {
3204 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
3205 hostdata->dstat_valid = 1;
3206 }
3207
3208 #if 1
3209
3210 if (!(hostdata->dstat & DSTAT_DFE)) {
3211 printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
3212 #if 0
3213 if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
3214 NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
3215 while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
3216 DSTAT_DFE));
3217 } else
3218 #endif
3219 {
3220 NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
3221 while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
3222 }
3223 }
3224 #endif
3225 }
3226 } while (interrupted);
3227
3228
3229
3230 if (hostdata->intrs != -1)
3231 hostdata->intrs++;
3232 #if 0
3233 if (hostdata->intrs > 4) {
3234 printk("scsi%d : too many interrupts, halting", host->host_no);
3235 hostdata->idle = 1;
3236 hostdata->options |= OPTION_DEBUG_INIT_ONLY;
3237 panic("dying...\n");
3238 }
3239 #endif
3240
3241 if (!hostdata->idle && hostdata->state == STATE_HALTED) {
3242 if (!hostdata->dsp_changed) {
3243 hostdata->dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
3244 }
3245
3246 #if 0
3247 printk("scsi%d : new dsp is 0x%lx\n", host->host_no,
3248 (long) hostdata->dsp);
3249 #endif
3250
3251 hostdata->state = STATE_RUNNING;
3252 NCR53c7x0_write32 (DSP_REG, (unsigned long) hostdata->dsp);
3253 }
3254 }
3255 } while (!done);
3256 }
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271 static int
3272 abort_connected (struct Scsi_Host *host) {
3273 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3274 host->hostdata;
3275
3276 hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
3277 sizeof(long);
3278 hostdata->dsp_changed = 1;
3279 printk ("scsi%d : DANGER : abort_connected() called \n",
3280 host->host_no);
3281
3282
3283
3284 return 0;
3285 }
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304 static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd
3305 *cmd) {
3306 NCR53c7x0_local_declare();
3307 unsigned long dbc_dcmd, *dsp, *dsp_next;
3308 unsigned char dcmd, sbcl;
3309 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3310 host->hostdata;
3311 char *phase;
3312 NCR53c7x0_local_setup(host);
3313
3314 if (!cmd) {
3315 printk ("scsi%d : phase mismatch interrupt occurred with no current command.\n",
3316 host->host_no);
3317 abort_connected(host);
3318 return;
3319 }
3320
3321
3322
3323
3324
3325
3326 dsp_next = (unsigned long *) NCR53c7x0_read32(DSP_REG);
3327
3328
3329
3330
3331
3332
3333
3334 dbc_dcmd = NCR53c7x0_read32(DBC_REG);
3335 dcmd = (dbc_dcmd & 0xff000000) >> 24;
3336 dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
3337
3338
3339
3340
3341
3342
3343
3344 sbcl = NCR53c7x0_read8(SBCL_REG);
3345 switch (sbcl) {
3346 case SBCL_PHASE_DATAIN:
3347 phase = "DATAIN";
3348 break;
3349 case SBCL_PHASE_DATAOUT:
3350 phase = "DATAOUT";
3351 break;
3352 case SBCL_PHASE_MSGIN:
3353 phase = "MSGIN";
3354 break;
3355 case SBCL_PHASE_MSGOUT:
3356 phase = "MSGOUT";
3357 break;
3358 case SBCL_PHASE_CMDOUT:
3359 phase = "CMDOUT";
3360 break;
3361 case SBCL_PHASE_STATIN:
3362 phase = "STATUSIN";
3363 break;
3364 default:
3365 phase = "unknown";
3366 break;
3367 }
3368
3369
3370
3371
3372
3373
3374
3375 if (dsp >= cmd->data_transfer_start & dsp < cmd->data_transfer_end) {
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385 switch (sbcl & SBCL_PHASE_MASK) {
3386
3387
3388
3389
3390 case SBCL_PHASE_STATIN:
3391 if (hostdata->options & OPTION_DEBUG_INTR)
3392 printk ("scsi%d : new phase = STATIN\n", host->host_no);
3393 hostdata->dsp = hostdata->script + hostdata->E_command_complete /
3394 sizeof(long);
3395 hostdata->dsp_changed = 1;
3396 return;
3397
3398
3399
3400
3401
3402
3403
3404 case SBCL_PHASE_MSGIN:
3405 if (hostdata->options & OPTION_DEBUG_INTR)
3406 printk ("scsi%d : new phase = MSGIN\n", host->host_no);
3407 if ((dcmd & (DCMD_TYPE_MASK|DCMD_BMI_OP_MASK|DCMD_BMI_INDIRECT|
3408 DCMD_BMI_MSG|DCMD_BMI_CD)) == (DCMD_TYPE_BMI|
3409 DCMD_BMI_OP_MOVE_I)) {
3410 dsp[0] = dbc_dcmd;
3411 dsp[1] = NCR53c7x0_read32(DNAD_REG);
3412 NCR53c7x0_write32(TEMP_REG, (unsigned long) dsp);
3413 hostdata->dsp = hostdata->script + hostdata->E_msg_in /
3414 sizeof(long);
3415 hostdata->dsp_changed = 1;
3416 } else {
3417 printk("scsi%d : unexpected MSGIN in dynamic NCR code, dcmd=0x%x.\n",
3418 host->host_no, dcmd);
3419 print_insn (host, dsp, "", 1);
3420 print_insn (host, dsp_next, "", 1);
3421 abort_connected (host);
3422 }
3423 return;
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434 default:
3435 printk ("scsi%d : unexpected phase %s in data routine\n",
3436 host->host_no, phase);
3437 abort_connected(host);
3438 }
3439
3440
3441
3442 } else {
3443 printk ("scsi%d : unexpected phase %s at dsp = 0x%x\n",
3444 host->host_no, phase, (unsigned) dsp);
3445 print_insn (host, dsp, "", 1);
3446 print_insn (host, dsp_next, "", 1);
3447 abort_connected(host);
3448 }
3449 }
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462 static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
3463 NCR53c7x0_local_declare();
3464 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3465 host->hostdata;
3466 unsigned char dstat;
3467 unsigned long *dsp,
3468 *next_dsp,
3469 *dsa,
3470 dbc_dcmd;
3471 int tmp;
3472 unsigned long flags;
3473 NCR53c7x0_local_setup(host);
3474
3475 if (!hostdata->dstat_valid) {
3476 hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
3477 hostdata->dstat_valid = 1;
3478 }
3479
3480 dstat = hostdata->dstat;
3481
3482 if (hostdata->options & OPTION_DEBUG_INTR)
3483 printk("scsi%d : DSTAT=0x%x\n", host->host_no, (int) dstat);
3484
3485 dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
3486 next_dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
3487 dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
3488
3489 dsa = (unsigned long *) NCR53c7x0_read32(DSA_REG);
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502 if (dstat & DSTAT_ABRT) {
3503 #if 0
3504
3505 if ((hostdata->options & OPTION_700) && (hostdata->state ==
3506 STATE_ABORTING) {
3507 } else
3508 #endif
3509 {
3510 printk("scsi%d : unexpected abort interrupt at\n"
3511 " ", host->host_no);
3512 print_insn (host, dsp, "s ", 1);
3513 panic(" ");
3514 }
3515 }
3516
3517
3518
3519
3520
3521
3522 if (dstat & DSTAT_SSI) {
3523 if (hostdata->options & OPTION_DEBUG_TRACE) {
3524 } else if (hostdata->options & OPTION_DEBUG_SINGLE) {
3525 print_insn (host, dsp, "s ", 0);
3526 save_flags(flags);
3527 cli();
3528
3529
3530 NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) &
3531 ~DCNTL_SSM) | DCNTL_STD);
3532 restore_flags(flags);
3533 } else {
3534 printk("scsi%d : unexpected single step interrupt at\n"
3535 " ", host->host_no);
3536 print_insn (host, dsp, "", 1);
3537 panic(" mail drew@colorad.edu\n");
3538 }
3539 }
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551 if (dstat & DSTAT_OPC) {
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564 if (((dsp >= (hostdata->script + hostdata->E_select / sizeof(long))) &&
3565 (dsp <= (hostdata->script + hostdata->E_select_msgout /
3566 sizeof(long) + 8))) || (hostdata->test_running == 2)) {
3567 if (hostdata->options & OPTION_DEBUG_INTR)
3568 printk ("scsi%d : ignoring DSTAT_IID for SSTAT_STO\n",
3569 host->host_no);
3570 if (hostdata->expecting_iid) {
3571 hostdata->expecting_iid = 0;
3572 hostdata->idle = 1;
3573 if (hostdata->test_running == 2) {
3574 hostdata->test_running = 0;
3575 hostdata->test_completed = 3;
3576 } else if (cmd)
3577 abnormal_finished (cmd, DID_BAD_TARGET << 16);
3578 } else {
3579 hostdata->expecting_sto = 1;
3580 }
3581 } else {
3582 printk("scsi%d : illegal instruction ", host->host_no);
3583 print_insn (host, dsp, "", 1);
3584 printk("scsi%d : DSP=0x%lx, DCMD|DBC=0x%lx, DSA=0x%lx\n"
3585 " DSPS=0x%lx, TEMP=0x%lx, DMODE=0x%x,\n"
3586 " DNAD=0x%lx\n",
3587 host->host_no, (unsigned long) dsp, dbc_dcmd,
3588 (unsigned long) dsa, NCR53c7x0_read32(DSPS_REG),
3589 NCR53c7x0_read32(TEMP_REG), (int) NCR53c7x0_read8(hostdata->dmode),
3590 NCR53c7x0_read32(DNAD_REG));
3591 panic(" mail drew@Colorado.EDU\n");
3592 }
3593 }
3594
3595
3596
3597
3598
3599
3600 if (dstat & DSTAT_800_BF) {
3601 printk("scsi%d : BUS FAULT, DSP=0x%lx, DCMD|DBC=0x%lx, DSA=0x%lx\n"
3602 " DSPS=0x%lx, TEMP=0x%lx, DMODE=0x%x\n",
3603 host->host_no, (unsigned long) dsp, NCR53c7x0_read32(DBC_REG),
3604 (unsigned long) dsa, NCR53c7x0_read32(DSPS_REG),
3605 NCR53c7x0_read32(TEMP_REG), (int) NCR53c7x0_read8(hostdata->dmode));
3606 print_dsa (host, dsa);
3607 printk("scsi%d : DSP->\n", host->host_no);
3608 print_insn(host, dsp, "", 1);
3609 print_insn(host, next_dsp, "", 1);
3610 #if 0
3611 panic(" mail drew@Colorado.EDU\n");
3612 #else
3613 hostdata->idle = 1;
3614 hostdata->options |= OPTION_DEBUG_INIT_ONLY;
3615 #endif
3616 }
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627 if (dstat & DSTAT_SIR) {
3628 if (hostdata->options & OPTION_DEBUG_INTR)
3629 printk ("scsi%d : DSTAT_SIR\n", host->host_no);
3630 switch ((tmp = hostdata->dstat_sir_intr (host, cmd))) {
3631 case SPECIFIC_INT_NOTHING:
3632 case SPECIFIC_INT_RESTART:
3633 break;
3634 case SPECIFIC_INT_ABORT:
3635 abort_connected(host);
3636 break;
3637 case SPECIFIC_INT_PANIC:
3638 printk("scsi%d : failure at ", host->host_no);
3639 print_insn (host, dsp, "", 1);
3640 panic(" dstat_sir_intr() returned SPECIFIC_INT_PANIC\n");
3641 break;
3642 case SPECIFIC_INT_BREAK:
3643 intr_break (host, cmd);
3644 break;
3645 default:
3646 printk("scsi%d : failure at ", host->host_no);
3647 print_insn (host, dsp, "", 1);
3648 panic(" dstat_sir_intr() returned unknown value %d\n",
3649 tmp);
3650 }
3651 }
3652
3653
3654 NCR53c7x0_write8 (STEST3_REG_800, STEST3_800_CSF);
3655 while (NCR53c7x0_read8 (STEST3_REG_800) & STEST3_800_CSF);
3656 }
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675 static int print_insn (struct Scsi_Host *host, unsigned long *insn,
3676 char *prefix, int kernel) {
3677 char buf[80],
3678 *tmp;
3679 unsigned char dcmd;
3680 int size;
3681
3682 dcmd = (insn[0] >> 24) & 0xff;
3683 sprintf(buf, "%s%08lx : 0x%08lx 0x%08lx", (prefix ? prefix : ""),
3684 (unsigned long) insn, insn[0], insn[1]);
3685 tmp = buf + strlen(buf);
3686 if ((dcmd & DCMD_TYPE_MASK) == DCMD_TYPE_MMI) {
3687 sprintf (tmp, " 0x%08lx\n", insn[2]);
3688 size = 3;
3689 } else {
3690 sprintf (tmp, "\n");
3691 size = 2;
3692 }
3693
3694 if (kernel)
3695 printk ("%s", buf);
3696 #ifdef NCR_DEBUG
3697 else {
3698 size_t len = strlen(buf);
3699 debugger_kernel_write(host, buf, len);
3700 }
3701 #endif
3702 return size;
3703 }
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717 int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
3718 struct Scsi_Host *host = cmd->host;
3719 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3720 host->hostdata;
3721 unsigned long flags;
3722 struct NCR53c7x0_cmd *curr, **prev;
3723 save_flags(flags);
3724 cli();
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736 for (curr = (struct NCR53c7x0_cmd *) hostdata->issue_queue,
3737 prev = (struct NCR53c7x0_cmd **) &(hostdata->issue_queue);
3738 curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **)
3739 &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
3740
3741 if (curr) {
3742 *prev = (struct NCR53c7x0_cmd *) curr->next;
3743
3744 if (curr->prev)
3745 curr->prev->next = curr->next;
3746
3747 curr->next = hostdata->free;
3748 hostdata->free = curr;
3749
3750 cmd->result = 0;
3751 cmd->scsi_done(cmd);
3752 restore_flags(flags);
3753 return SCSI_ABORT_SUCCESS;
3754 }
3755
3756
3757
3758
3759
3760
3761 for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list,
3762 prev = (struct NCR53c7x0_cmd **) &(hostdata->running_list);
3763 curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **)
3764 &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
3765
3766 if (curr) {
3767 restore_flags(flags);
3768 printk ("scsi%d : DANGER : command in running list, can not abort.\n",
3769 cmd->host->host_no);
3770 return SCSI_ABORT_SNOOZE;
3771 }
3772
3773
3774
3775
3776
3777
3778
3779 curr = (struct NCR53c7x0_cmd *) cmd->host_scribble;
3780 curr->next = hostdata->free;
3781 hostdata->free = curr;
3782
3783 if (((cmd->result & 0xff00) == 0xff00) ||
3784 ((cmd->result & 0xff) == 0xff)) {
3785 printk ("scsi%d : did this command ever run?\n", host->host_no);
3786 } else {
3787 printk ("scsi%d : probably lost INTFLY, normal completion\n",
3788 host->host_no);
3789 }
3790 cmd->scsi_done(cmd);
3791 restore_flags(flags);
3792 return SCSI_ABORT_SNOOZE;
3793 }
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806 int
3807 NCR53c7xx_reset (Scsi_Cmnd *cmd) {
3808 NCR53c7x0_local_declare();
3809 unsigned long flags;
3810 int found;
3811 struct NCR53c7x0_cmd * c;
3812 Scsi_Cmnd *tmp;
3813 struct Scsi_Host *host = cmd->host;
3814 struct NCR53c7x0_hostdata *hostdata = host ?
3815 (struct NCR53c7x0_hostdata *) host->hostdata : NULL;
3816 NCR53c7x0_local_setup(host);
3817 save_flags(flags);
3818 halt (host);
3819 NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
3820 udelay(25);
3821 NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
3822 for (c = (struct NCR53c7x0_cmd *) hostdata->running_list, found = 0; c;
3823 c = (struct NCR53c7x0_cmd *) c->next) {
3824 tmp = c->cmd;
3825 c->next = hostdata->free;
3826 hostdata->free = c;
3827
3828 if (tmp == cmd)
3829 found = 1;
3830 tmp->result = DID_RESET << 16;
3831 tmp->scsi_done(tmp);
3832 }
3833 if (!found) {
3834 c = (struct NCR53c7x0_cmd *) cmd->host_scribble;
3835 if (c) {
3836 c->next = hostdata->free;
3837 hostdata->free = c;
3838 }
3839 cmd->result = DID_RESET << 16;
3840 cmd->scsi_done(cmd);
3841 }
3842 restore_flags(flags);
3843
3844 printk ("scsi%d : DANGER : NCR53c7xx_reset is NOP\n",
3845 cmd->host->host_no);
3846 return SCSI_RESET_SUCCESS;
3847 }
3848
3849
3850
3851
3852
3853
3854 static void print_dsa (struct Scsi_Host *host, unsigned long *dsa) {
3855 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3856 host->hostdata;
3857 int i, len;
3858 char *ptr;
3859
3860 printk("scsi%d : dsa at 0x%x\n"
3861 " + %ld : dsa_msgout length = %lu, data = 0x%lx\n" ,
3862 host->host_no, (unsigned) dsa, hostdata->dsa_msgout,
3863 dsa[hostdata->dsa_msgout / sizeof(long)],
3864 dsa[hostdata->dsa_msgout / sizeof(long) + 1]);
3865
3866 for (i = dsa[hostdata->dsa_msgout / sizeof(long)],
3867 ptr = (char *) dsa[hostdata->dsa_msgout / sizeof(long) + 1]; i > 0;
3868 ptr += len, i -= len) {
3869 printk(" ");
3870 len = print_msg (ptr);
3871 printk("\n");
3872 }
3873 }
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884 #ifdef MODULE
3885 static int
3886 shutdown (struct Scsi_Host *host) {
3887 NCR53c7x0_local_declare();
3888 unsigned long flags;
3889 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3890 host->hostdata;
3891 NCR53c7x0_local_setup(host);
3892 save_flags (flags);
3893 cli();
3894 halt (host);
3895 hostdata->soft_reset(host);
3896
3897
3898
3899
3900
3901
3902
3903 NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
3904 udelay(25);
3905 NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
3906 restore_flags (flags);
3907 return 0;
3908 }
3909 #endif
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922 static int
3923 halt (struct Scsi_Host *host) {
3924 NCR53c7x0_local_declare();
3925 unsigned long flags;
3926 unsigned char istat, tmp;
3927 struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3928 host->hostdata;
3929 NCR53c7x0_local_setup(host);
3930
3931 save_flags(flags);
3932 cli();
3933 NCR53c7x0_write8(hostdata->istat, ISTAT_ABRT);
3934
3935 for (;;) {
3936 istat = NCR53c7x0_read8 (hostdata->istat);
3937 if (istat & ISTAT_SIP) {
3938 if ((hostdata->chip / 100) == 8) {
3939 tmp = NCR53c7x0_read8(SIST0_REG_800);
3940 udelay(1);
3941 tmp = NCR53c7x0_read8(SIST1_REG_800);
3942 } else {
3943 tmp = NCR53c7x0_read8(SSTAT0_REG);
3944 }
3945 } else if (istat & ISTAT_DIP) {
3946 NCR53c7x0_write8(hostdata->istat, 0);
3947 tmp = NCR53c7x0_read8(DSTAT_REG);
3948 if (tmp & DSTAT_ABRT)
3949 break;
3950 else
3951 panic("scsi%d: could not halt NCR chip\n", host->host_no);
3952 }
3953 }
3954 hostdata->state = STATE_HALTED;
3955 restore_flags(flags);
3956 return 0;
3957 }
3958
3959 #ifdef MODULE
3960 int NCR53c7x0_release(struct Scsi_Host *host) {
3961 shutdown (host);
3962
3963 if (host->irq != IRQ_NONE)
3964 {
3965 int irq_count;
3966 struct Scsi_Host *tmp;
3967 for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
3968 if (tmp->hostt == the_template && tmp->irq == host->irq)
3969 ++irq_count;
3970 if (irq_count == 1)
3971 free_irq(host->irq);
3972 }
3973 if (host->dma_channel != DMA_NONE)
3974 free_dma(host->dma_channel);
3975 return 1;
3976 }
3977 Scsi_Host_Template driver_template = NCR53c7xx;
3978 #include "scsi_module.c"
3979 #endif